// @flow import React from 'react' import PropTypes from 'prop-types' import { shallow } from 'enzyme' import { resetStyled, expectCSSMatches } from './utils' let styled describe('extending', () => { /** * Make sure the setup is the same for every test */ beforeEach(() => { styled = resetStyled() }) it('should generate empty classes with no styles', () => { const Parent = styled.div`` const Child = Parent.extend`` shallow() shallow() expectCSSMatches('.sc-a {} .sc-b {}') }) it('should attach styles to both classes if only parent has styles', () => { const Parent = styled.div` color: blue; ` const Child = Parent.extend`` shallow() shallow() expectCSSMatches('.sc-a {} .c { color:blue; } .sc-b {} .d { color:blue; }') }) it('should attach styles to child class if only child has styles', () => { const Parent = styled.div`` const Child = Parent.extend` color: blue; ` shallow() shallow() expectCSSMatches('.sc-a {} .sc-b {} .d { color:blue; }') }) it('should generate a class for the child with the rules of the parent', () => { const Parent = styled.div` color: blue; ` const Child = Parent.extend` color: red; ` shallow() expectCSSMatches('.sc-b {} .c { color:blue;color:red; }') }) it('should generate different classes for both parent and child', () => { const Parent = styled.div` color: blue; ` const Child = Parent.extend` color: red; ` shallow() shallow() expectCSSMatches( '.sc-a {} .c { color:blue; } .sc-b {} .d { color:blue;color:red; }' ) }) it('should copy nested rules to the child', () => { const Parent = styled.div` color: blue; > h1 { font-size: 4rem; } ` const Child = Parent.extend` color: red; ` shallow() shallow() expectCSSMatches(` .sc-a {} .c{ color:blue; } .c > h1{ font-size:4rem; } .sc-b {} .d { color:blue; color:red; } .d > h1 { font-size:4rem; } `) }) it('should keep default props from parent', () => { const Parent = styled.div` color: ${props => props.color}; ` Parent.defaultProps = { color: 'red', } const Child = Parent.extend` background-color: green; ` shallow() shallow() expectCSSMatches(` .sc-a {} .c { color:red; } .sc-b {} .d { color:red; background-color:green; } `) }) it('should keep prop types from parent', () => { const Parent = styled.div` color: ${props => props.color}; ` Parent.propTypes = { color: PropTypes.string, } const Child = Parent.extend` background-color: green; ` expect(Child.propTypes).toEqual(Parent.propTypes) }) it('should keep custom static member from parent', () => { const Parent = styled.div` color: red; ` Parent.fetchData = () => 1 const Child = Parent.extend` color: green; ` expect(Child.fetchData).toBeTruthy() expect(Child.fetchData()).toEqual(1) }) it('should keep static member in triple inheritance', () => { const GrandParent = styled.div` color: red; ` GrandParent.fetchData = () => 1 const Parent = GrandParent.extend` color: red; ` const Child = Parent.extend` color: red; ` expect(Child.fetchData).toBeTruthy() expect(Child.fetchData()).toEqual(1) }) it('should keep styles in >= 3 inheritances', () => { const GrandGrandParent = styled.div` background-color: red; ` const GrandParent = GrandGrandParent.extend` color: blue; ` const Parent = GrandParent.extend` border: 2px solid black; ` const Child = Parent.extend` border-width: 10; ` shallow() shallow() shallow() shallow() expectCSSMatches(` .sc-a { } .e { background-color:red; } .sc-b { } .f { background-color:red; color:blue; } .sc-c { } .g { background-color:red; color:blue; border:2px solid black; } .sc-d { } .h { background-color:red; color:blue; border:2px solid black; border-width:10; } `) }) it('should allow changing component', () => { const Parent = styled.div` color: red; ` const Child = Parent.withComponent('span') expect(shallow().html()).toEqual('') }) it('should allow changing component and extending', () => { const Parent = styled.div` color: red; ` const Child = Parent.withComponent('span').extend` color: green; ` expect(shallow().html()).toEqual('') expectCSSMatches(` .sc-c {} .d { color:red; color:green; } `) }) it('should allow changing component and adding attributes', () => { const Parent = styled.button` color: red; ` const Child = Parent.withComponent('a').extend.attrs({ href: '/test', })`` expect(shallow().html()).toEqual( '' ) }) it('regression test for #1781, extending a Styled(StyledComponent)', () => { const Title = styled.h1` color: red; ` const ExtendedTitle = styled(Title)` background-color: blue; ` const ExtendedExtendedTitle = ExtendedTitle.extend` border: 2px solid green; ` expect(shallow().html()).toMatchSnapshot() expectCSSMatches(` .sc-a { } .e { color:red; } .sc-c { } .d { background-color:blue; border:2px solid green; } `) }) })