// @flow
import React, { Component } from 'react'
import { shallow } from 'enzyme'
import { resetStyled, expectCSSMatches } from './utils'
let styled
describe('attrs', () => {
beforeEach(() => {
styled = resetStyled()
})
it('work fine with an empty object', () => {
const Comp = styled.div.attrs({})``
expect(shallow( ).html()).toEqual('
')
})
it('pass a simple attr', () => {
const Comp = styled.button.attrs({
type: 'button',
})``
expect(shallow( ).html()).toEqual(
' '
)
})
it('pass a React component', () => {
// $FlowFixMe
class ReactComponent extends Component {
render() {
return React Component
}
}
const Button = ({ component: ChildComponent }) => (
)
const Comp = styled(Button).attrs({
component: ReactComponent,
})``
expect(shallow( ).html()).toEqual(
'React Component
'
)
})
it('call an attr function', () => {
const Comp = styled.button.attrs({
type: () => 'button',
})``
expect(shallow( ).html()).toEqual(
' '
)
})
it('pass props to the attr function', () => {
const Comp = styled.button.attrs({
type: props => (props.submit ? 'submit' : 'button'),
})``
expect(shallow( ).html()).toEqual(
' '
)
expect(shallow( ).html()).toEqual(
' '
)
})
it('should replace attrs with props', () => {
const Comp = styled.button.attrs({
type: props => (props.submit ? 'submit' : 'button'),
tabIndex: 0,
})``
expect(shallow( ).html()).toEqual(
' '
)
expect(shallow( ).html()).toEqual(
' '
)
expect(shallow( ).html()).toEqual(
' '
)
})
it('should merge className', () => {
const Comp = styled.div.attrs({
className: 'meow nya',
})``
expect(shallow( ).html()).toEqual(
'
'
)
})
it('should merge className even if its a function', () => {
const Comp = styled.div.attrs({
className: props => `meow ${props.purr ? 'purr' : 'nya'}`,
})``
expect(shallow( ).html()).toEqual(
'
'
)
expect(shallow( ).html()).toEqual(
'
'
)
})
it('should work with data and aria attributes', () => {
const Comp = styled.div.attrs({
'data-foo': 'bar',
'aria-label': 'A simple FooBar',
})``
expect(shallow( ).html()).toEqual(
'
'
)
})
it('merge attrs', () => {
const Comp = styled.button
.attrs({
type: 'button',
tabIndex: 0,
})
.attrs({
type: 'submit',
})``
expect(shallow( ).html()).toEqual(
' '
)
})
it('merge attrs when inheriting SC', () => {
const Parent = styled.button.attrs({
type: 'button',
tabIndex: 0,
})``
const Child = Parent.extend.attrs({
type: 'submit',
})``
expect(shallow( ).html()).toEqual(
' '
)
})
it('pass attrs to style block', () => {
/* Would be a React Router Link in real life */
const Comp = styled.a.attrs({
href: '#',
'data-active-class-name': '--is-active',
})`
color: blue;
&.${props => props['data-active-class-name']} {
color: red;
}
`
expect(shallow( ).html()).toEqual(
' '
)
expectCSSMatches(
'.sc-a {} .b { color:blue; } .b.--is-active { color:red; }'
)
})
it('should pass through children as a normal prop', () => {
const Comp = styled.div.attrs({
children: 'Probably a bad idea',
})``
expect(shallow( ).html()).toEqual(
'Probably a bad idea
'
)
})
it('should pass through complex children as well', () => {
const Comp = styled.div.attrs({
children: Probably a bad idea ,
})``
expect(shallow( ).html()).toEqual(
'Probably a bad idea
'
)
})
it('should override children of course', () => {
const Comp = styled.div.attrs({
children: Amazing ,
})``
expect(shallow(Something else ).html()).toEqual(
'Something else
'
)
})
it('should shallow merge "style" prop + attr instead of overwriting', () => {
const Paragraph = styled.p.attrs({
style: props => ({
...props.style,
fontSize: `${props.fontScale}em`,
}),
})``
class Text extends React.Component {
state = {
// Assume that will be changed automatically
// according to the dimensions of the container
fontScale: 4,
}
render() {
return (
{this.props.children}
)
}
}
const BlueText = styled(Text).attrs({
style: props => ({
color: 'blue',
}),
})``
expect(shallow(Hello ).html()).toEqual(
'Hello
'
)
})
})