mirror of
https://github.com/zhigang1992/react.git
synced 2026-01-31 22:41:29 +08:00
@@ -12,9 +12,11 @@ module.exports = {
|
||||
},
|
||||
|
||||
testRegex: '.*\\.test\\.(j|t)sx?$',
|
||||
// testRegex: 'button\\/.*\\.test\\.(j|t)sx?$',
|
||||
|
||||
collectCoverageFrom: [
|
||||
'components/**/*.{ts,tsx}',
|
||||
'!components/**/styles.{ts,tsx}',
|
||||
'!components/styles/*',
|
||||
'!components/index.ts',
|
||||
],
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Button should render empty button correctly 1`] = `
|
||||
<Memo
|
||||
auto={false}
|
||||
className=""
|
||||
disabled={false}
|
||||
effect={true}
|
||||
ghost={false}
|
||||
loading={false}
|
||||
shadow={false}
|
||||
size="medium"
|
||||
type="default"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`Button should render special styles 1`] = `ReactWrapper {}`;
|
||||
|
||||
exports[`Button should render special styles 2`] = `
|
||||
<Memo
|
||||
auto={false}
|
||||
className=""
|
||||
disabled={false}
|
||||
effect={true}
|
||||
ghost={false}
|
||||
loading={true}
|
||||
shadow={false}
|
||||
size="medium"
|
||||
type="default"
|
||||
>
|
||||
button
|
||||
</Memo>
|
||||
`;
|
||||
128
components/button/__tests__/index.test.tsx
Normal file
128
components/button/__tests__/index.test.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import React from 'react'
|
||||
import { mount } from 'enzyme'
|
||||
import { Button } from '../../'
|
||||
import { sleep } from '../../../tests/utils'
|
||||
|
||||
describe('Button', () => {
|
||||
it('should render correctly', () => {
|
||||
const wrapper = mount(<Button>Button</Button>)
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should support all types', () => {
|
||||
const wrapper = mount(
|
||||
<div>
|
||||
<Button type="secondary" />
|
||||
<Button type="success" />
|
||||
<Button type="warning" />
|
||||
<Button type="error" />
|
||||
<Button type="abort" />
|
||||
</div>
|
||||
)
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should support all sizes', () => {
|
||||
const wrapper = mount(
|
||||
<div>
|
||||
<Button size="mini" />
|
||||
<Button size="small" />
|
||||
<Button size="medium" />
|
||||
<Button size="large" />
|
||||
</div>
|
||||
)
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should render different text', () => {
|
||||
const wrapper = mount(<Button>button</Button>)
|
||||
expect(wrapper.text()).toContain('button')
|
||||
|
||||
wrapper.setProps({
|
||||
children: <span>按钮</span>,
|
||||
})
|
||||
expect(wrapper.text()).toContain('按钮')
|
||||
})
|
||||
|
||||
it('should render empty button correctly', () => {
|
||||
expect(<Button></Button>).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should trigger callback function', () => {
|
||||
const WrapperButton = () => {
|
||||
const [state, setState] = React.useState<string>('state1')
|
||||
return (
|
||||
<Button onClick={() => setState('state2')}>
|
||||
{state}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
const wrapper = mount(<WrapperButton />)
|
||||
expect(wrapper.text()).toContain('state1')
|
||||
|
||||
wrapper.simulate('click')
|
||||
expect(wrapper.text()).toContain('state2')
|
||||
})
|
||||
|
||||
it('should ignore events when disabled', () => {
|
||||
const WrapperButton = () => {
|
||||
const [state, setState] = React.useState<string>('state1')
|
||||
return (
|
||||
<Button disabled onClick={() => setState('state2')}>
|
||||
{state}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
const wrapper = mount(<WrapperButton />)
|
||||
expect(wrapper.text()).toContain('state1')
|
||||
|
||||
wrapper.simulate('click')
|
||||
expect(wrapper.text()).toContain('state1')
|
||||
expect(wrapper.text()).not.toContain('state2')
|
||||
})
|
||||
|
||||
it('should ignore events when loading', () => {
|
||||
const WrapperButton = () => {
|
||||
const [state, setState] = React.useState<string>('state1')
|
||||
return (
|
||||
<Button loading onClick={() => setState('state2')}>
|
||||
{state}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
const wrapper = mount(<WrapperButton />)
|
||||
wrapper.simulate('click')
|
||||
expect(wrapper.text()).not.toContain('state2')
|
||||
})
|
||||
|
||||
it('should render special styles', () => {
|
||||
const wrapper = mount(
|
||||
<div>
|
||||
<Button ghost>button</Button>
|
||||
<Button ghost type="success">button</Button>
|
||||
<Button ghost type="warning">button</Button>
|
||||
<Button ghost loading>button</Button>
|
||||
<Button shadow>button</Button>
|
||||
<Button auto>button</Button>
|
||||
<Button effect={false}>button</Button>
|
||||
</div>
|
||||
)
|
||||
expect(wrapper).toMatchSnapshot()
|
||||
expect(<Button loading>button</Button>).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should remove expired events', () => {
|
||||
const wrapper = mount(<Button>button</Button>)
|
||||
wrapper.simulate('click')
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should support loading change with deply', async () => {
|
||||
const wrapper = mount(<Button>button</Button>)
|
||||
wrapper.simulate('click')
|
||||
await sleep(500)
|
||||
wrapper.setProps({ loading: true })
|
||||
await sleep(500)
|
||||
expect(wrapper.find('.loading-container').length).not.toBe(0)
|
||||
})
|
||||
})
|
||||
@@ -2,8 +2,8 @@ import React, { useEffect, useRef } from 'react'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
|
||||
interface Props {
|
||||
x?: number
|
||||
y?: number
|
||||
x: number
|
||||
y: number
|
||||
color?: string
|
||||
onCompleted?: Function
|
||||
}
|
||||
@@ -20,10 +20,17 @@ const ButtonDrip: React.FC<ButtonDrip> = React.memo(({
|
||||
x, y, color, onCompleted
|
||||
}) => {
|
||||
const dripRef = useRef<HTMLDivElement>(null)
|
||||
/* istanbul ignore next */
|
||||
const top = Number.isNaN(+y) ? 0 : y - 10
|
||||
/* istanbul ignore next */
|
||||
const left = Number.isNaN(+x) ? 0 : x - 10
|
||||
|
||||
useEffect(() => {
|
||||
/* istanbul ignore next */
|
||||
if (!dripRef.current) return
|
||||
dripRef.current.addEventListener('animationend', onCompleted)
|
||||
return () => {
|
||||
/* istanbul ignore next */
|
||||
if (!dripRef.current) return
|
||||
dripRef.current.removeEventListener('animationend', onCompleted)
|
||||
}
|
||||
@@ -32,7 +39,7 @@ const ButtonDrip: React.FC<ButtonDrip> = React.memo(({
|
||||
return (
|
||||
<div ref={dripRef} className="drip">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20"
|
||||
style={{ top: y - 10, left: x - 10 }}>
|
||||
style={{ top, left }}>
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g fill={color}><rect width="100%" height="100%" rx="10" /></g>
|
||||
</g>
|
||||
|
||||
@@ -60,6 +60,7 @@ const Button: React.FC<React.PropsWithChildren<ButtonProps>> = React.memo(({
|
||||
[size, auto],
|
||||
)
|
||||
|
||||
/* istanbul ignore next */
|
||||
const dripCompletedHandle = () => {
|
||||
setDripShow(false)
|
||||
setDripX(0)
|
||||
@@ -69,6 +70,7 @@ const Button: React.FC<React.PropsWithChildren<ButtonProps>> = React.memo(({
|
||||
const clickHandler = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
if (disabled || loading) return
|
||||
const showDrip = !shadow && !ghost && effect
|
||||
/* istanbul ignore next */
|
||||
if (showDrip && buttonRef.current) {
|
||||
const rect = buttonRef.current.getBoundingClientRect()
|
||||
setDripShow(true)
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-transform-runtime": "^7.9.0",
|
||||
"@babel/preset-typescript": "^7.8.3",
|
||||
"@mapbox/rehype-prism": "^0.4.0",
|
||||
"@mdx-js/loader": "^1.5.7",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
|
||||
plugins: ['styled-jsx/babel-test'],
|
||||
plugins: ['styled-jsx/babel-test', '@babel/plugin-transform-runtime'],
|
||||
}
|
||||
|
||||
3
tests/utils.ts
Normal file
3
tests/utils.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const sleep = (time: number) => {
|
||||
return new Promise(resolve => setTimeout(resolve, time))
|
||||
}
|
||||
10
yarn.lock
10
yarn.lock
@@ -865,6 +865,16 @@
|
||||
resolve "^1.8.1"
|
||||
semver "^5.5.1"
|
||||
|
||||
"@babel/plugin-transform-runtime@^7.9.0":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b"
|
||||
integrity sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.8.3"
|
||||
"@babel/helper-plugin-utils" "^7.8.3"
|
||||
resolve "^1.8.1"
|
||||
semver "^5.5.1"
|
||||
|
||||
"@babel/plugin-transform-shorthand-properties@^7.2.0":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8"
|
||||
|
||||
Reference in New Issue
Block a user