import React, { useRef } from 'react'
import {
Animated,
ScrollView,
Text,
TouchableWithoutFeedback,
} from 'react-native'
import renderer, { ReactTestRendererJSON } from 'react-test-renderer'
import { renderHook } from '@testing-library/react-hooks'
import { styl, Provider, useTheme } from '.'
describe('styl', () => {
describe('render', () => {
it('renders correctly', () => {
const Title = styl(Text)({})
const tree = renderer.create(
).toJSON()
expect(tree).toMatchSnapshot()
})
it('renders a type of original component', () => {
const Title = styl(Text)({})
const tree = renderer.create().toJSON() as ReactTestRendererJSON
expect(tree.type).toBe('Text')
expect(tree).toMatchSnapshot()
})
})
describe('style', () => {
it('accepts inline style', () => {
const GOAL = 'blue'
const Title = styl(Text)({})
const render = renderer.create()
// Check tree
const tree = render.toJSON() as ReactTestRendererJSON
const styles = { ...tree.props.style[0], ...tree.props.style[1] }
expect(styles.color).toBe(GOAL)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
it('its inline style override the original style', () => {
const WRONG = 'red'
const GOAL = 'blue'
const Title = styl(Text)({ color: WRONG })
const render = renderer.create()
// Check tree
const tree = render.toJSON() as ReactTestRendererJSON
const styles = { ...tree.props.style[0], ...tree.props.style[1] }
expect(styles.color).toBe(GOAL)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
it('empty inline style does not remove the original style', () => {
const GOAL = 'blue'
const Title = styl(Text)({ color: GOAL })
const render = renderer.create()
// Check tree
const tree = render.toJSON() as ReactTestRendererJSON
const styles = { ...tree.props.style[0], ...tree.props.style[1] }
expect(styles.color).toBe(GOAL)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
})
describe('props', () => {
it('renders custom props', () => {
enum GOAL {
'blue' = 'blue',
}
const Title = styl(Text)<{ color: GOAL }>(({ props }) => ({
color: props.color,
}))
const render = renderer.create()
// Check tree
const tree = render.toJSON() as ReactTestRendererJSON
const styles = { ...tree.props.style[0], ...tree.props.style[1] }
expect(styles.color).toBe(GOAL.blue)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
it('polymorphic > TouchableWithoutFeedback', () => {
const ORIGINAL = Text
const GOAL = TouchableWithoutFeedback
const fn = jest.fn()
const Comp = styl(ORIGINAL)({ color: 'blue' })
const render = renderer.create(
TouchableWithoutFeedback
)
// Check tree
const tree = render.toTree()
expect(tree?.instance instanceof GOAL).toBe(true)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
// Event onPress has been called
tree?.props.onPress()
expect(fn).toBeCalled()
})
it('polymorphic > ScrollView', () => {
const ORIGINAL = Text
const GOAL = ScrollView
const Comp = styl(ORIGINAL)({ color: 'blue' })
const render = renderer.create(
TouchableWithoutFeedback
)
// Check tree
const tree = render.toTree()
expect(tree?.instance instanceof GOAL).toBe(true)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
it('polymorphic merge props', () => {
const Title = styl(Text)<{ color?: string }>({ color: 'blue' })
const render = renderer.create(Text)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
it('polymorphic animated style props', () => {
// Normal
const TitleNormal = styl(Text)<{ color?: string }>({ color: 'blue' })
renderer.create(Text)
// Animated
const TextAnimated = Animated.createAnimatedComponent(Text)
const TitleAnimated = styl(TextAnimated)<{ color?: string }>({
color: 'blue',
})
const render = renderer.create(
Text
)
// Snapshot
const json = render.toJSON()
expect(json).toMatchSnapshot()
})
})
describe('theme/provider', () => {
it('gets the color from theme', () => {
const GOAL = 'blue'
const ProviderTheme: React.FC = ({ children }) => (
{children}
)
const Title = styl(Text)(({ theme }: any) => ({
color: theme.primary,
}))
const tree = renderer
.create(
)
.toJSON() as ReactTestRendererJSON
const styles = { ...tree.props.style[0], ...tree.props.style[1] }
expect(styles.color).toBe(GOAL)
expect(tree).toMatchSnapshot()
})
it('gets the color from nested theme', () => {
const WRONG_COLOR = 'red'
const GOAL = 'blue'
const ThemeA: React.FC = ({ children }) => (
{children}
)
const ThemeB: React.FC = ({ children }) => (
{children}
)
const Title = styl(Text)(({ theme }: any) => ({
color: theme.primary,
}))
const tree = renderer
.create(
)
.toJSON() as ReactTestRendererJSON
const styles = { ...tree.props.style[0], ...tree.props.style[1] }
expect(styles.color).toBe(GOAL)
expect(tree).toMatchSnapshot()
})
it('useTheme', () => {
const theme = { color: 'red' }
const wrapper: React.FC = ({ children }) => (
{children}
)
const { result } = renderHook(() => useTheme(), { wrapper })
expect((result.current as typeof theme).color).toBe(theme.color)
})
})
describe('ref', () => {
it('gets proper ref', () => {
let ref: any
const Title = styl(Text)({})
const Element = () => {
// reassign in a new context
ref = useRef()
return
}
renderer.create().toTree()
expect(ref.current instanceof Text).toBe(true)
})
it('polymorphic', () => {
let ref: any
const Title = styl(Text)<{ color: string }>({})
const Element = () => {
// reassign in a new context
ref = useRef()
return
}
renderer.create().toJSON()
expect(ref.current instanceof ScrollView).toBe(true)
})
})
})