diff --git a/package.json b/package.json index 72bd2b9d1..56d11c584 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,7 @@ "webpack": "^4.16.5", "webpack-dev-server": "^3.1.5", "webpack-merge": "^4.1.3", - "yaml-loader": "^0.5.0" + "yaml-loader": "^0.5.0", + "simulant": "^0.2.2" } } diff --git a/src/components/swipe-action/index.js b/src/components/swipe-action/index.js index ab0543f91..f324d518f 100644 --- a/src/components/swipe-action/index.js +++ b/src/components/swipe-action/index.js @@ -14,10 +14,10 @@ export default class AtSwipeAction extends AtComponent { constructor () { super(...arguments) + this.endValue = 0 this.startX = null - this.maxOffsetSize = 0 this.isTouching = false - this.endValue = 0 + this.maxOffsetSize = 0 this.state = { offsetSize: 0, @@ -31,28 +31,19 @@ export default class AtSwipeAction extends AtComponent { if (isClose && isOpened) { this._reset() + this.handleClosed() } } _reset () { this.endValue = 0 this.isTouching = false - this.handleClosed() this.setState({ - isOpened: false, - offsetSize: 0 + offsetSize: 0, + isOpened: false }) } - handleTouchStart = e => { - const { clientX } = e.touches[0] - - if (this.props.disabled) return - - this.startX = clientX - this.isTouching = true - } - handleOpened = () => { if (_isFunction(this.props.onOpened) && !this.state.isOpened) { this.props.onOpened() @@ -65,6 +56,15 @@ export default class AtSwipeAction extends AtComponent { } } + handleTouchStart = e => { + const { clientX } = e.touches[0] + + if (this.props.disabled) return + + this.startX = clientX + this.isTouching = true + } + handleTouchEnd = () => { this.isTouching = false @@ -113,11 +113,13 @@ export default class AtSwipeAction extends AtComponent { handleClick = (item, index, ...arg) => { const { onClick, autoClose } = this.props + if (_isFunction(onClick)) { onClick(item, index, ...arg) } if (autoClose) { this._reset() + this.handleClosed() } } diff --git a/src/components/swipe-action/index.test.js b/src/components/swipe-action/index.test.js index fa2b591cf..d72712f80 100644 --- a/src/components/swipe-action/index.test.js +++ b/src/components/swipe-action/index.test.js @@ -1,11 +1,58 @@ import Nerv, { findDOMNode } from 'nervjs' import { renderToString } from 'nerv-server' -import { Simulate, renderIntoDocument } from 'nerv-test-utils' +import { renderIntoDocument } from 'nerv-test-utils' +import simulant from 'simulant' import { View } from '@tarojs/components' import AtSwipeAction from '../../../.temp/components/swipe-action/index' +const MAX_OFFSET_SIZE = 101 + +const Simulate = {} +const EVENTS = [ + 'keyDown', + 'keyPress', + 'keyUp', + 'focus', + 'blur', + 'click', + 'contextMenu', + 'doubleClick', + 'drag', + 'dragEnd', + 'dragEnter', + 'dragExit', + 'dragLeave', + 'dragOver', + 'dragStart', + 'drop', + 'mouseDown', + 'mouseEnter', + 'mouseLeave', + 'mouseMove', + 'mouseOut', + 'mouseOver', + 'mouseUp', + 'change', + 'input', + 'submit', + 'touchCancel', + 'touchEnd', + 'touchMove', + 'touchStart', + 'load', + 'error', + 'animationStart', + 'animationEnd', + 'animationIteration', + 'transitionEnd' +] +EVENTS.forEach(event => { + Simulate[event] = (node, mock) => + simulant.fire(node, event.toLowerCase(), mock) +}) + const OPTIONS = [ { text: '取消', @@ -39,21 +86,239 @@ describe('SwipeAction Snap', () => { }) }) -describe('SwipeAction Behavior ', () => { +describe('SwipeAction Swipe Behavior', () => { + const onClick = jest.fn() + const onClosed = jest.fn() + const onOpened = jest.fn() + + const component = renderIntoDocument( + + AtSwipeAction 一般使用场景 + + ) + const componentDom = findDOMNode(component, 'at-swipe-action') + component.maxOffsetSize = MAX_OFFSET_SIZE + + beforeEach(() => { + onClick.mockReset() + onClosed.mockReset() + onOpened.mockReset() + component._reset() + }) + it('SwipeAction onClick', () => { - const onClick = jest.fn() + const optionDom = componentDom.querySelector('.at-swipe-action__option') + + Simulate.click(optionDom) + + expect(onClick).toBeCalled() + }) + + it('SwipeAction Swipe Right', () => { + // 一开始向右滑动是没有效果的 + expect(component.isTouching).toBeFalsy() + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + expect(component.isTouching).toBeTruthy() + + Simulate.touchMove(componentDom, { + touches: [{ clientX: 100 }] + }) + + component.forceUpdate() + expect(component.state.offsetSize).toEqual(0) + + Simulate.touchEnd(componentDom) + expect(onClosed).not.toBeCalled() + expect(onOpened).not.toBeCalled() + expect(component.state.isOpened).toBeFalsy() + expect(component.state.offsetSize).toEqual(0) + }) + it('SwipeAction Swipe Left', () => { + // 一开始向左滑动 直到最大时将停止 + expect(component.isTouching).toBeFalsy() + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + expect(component.isTouching).toBeTruthy() + + Simulate.touchMove(componentDom, { + touches: [{ clientX: -110 }] + }) + + component.forceUpdate() + expect(component.state.offsetSize).toEqual(-110) + + Simulate.touchEnd(componentDom) + component.forceUpdate() + + expect(onOpened).toBeCalled() + expect(onClosed).not.toBeCalled() + expect(component.state.isOpened).toBeTruthy() + expect(component.state.offsetSize).toEqual(-MAX_OFFSET_SIZE) + }) + + it('SwipeAction Completed Swipe Action', () => { + // 开始向左滑懂 + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + + Simulate.touchMove(componentDom, { + touches: [{ clientX: -100 }] + }) + + component.forceUpdate() + expect(component.state.offsetSize).toEqual(-100) + + // 向左滑动结束 + Simulate.touchEnd(componentDom) + component.forceUpdate() + + expect(onOpened).toBeCalled() + expect(component.state.isOpened).toBeTruthy() + expect(component.endValue).toEqual(-MAX_OFFSET_SIZE) + expect(component.state.offsetSize).toEqual(-MAX_OFFSET_SIZE) + + // 开始向右滑动 + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + + Simulate.touchMove(componentDom, { + touches: [{ clientX: 100 }] + }) + + component.forceUpdate() + expect(component.state.offsetSize).toEqual(-1) + + // 向右滑动结束 + Simulate.touchEnd(componentDom) + component.forceUpdate() + expect(onClosed).toBeCalled() + expect(component.endValue).toEqual(0) + expect(component.state.isOpened).toBeFalsy() + expect(component.state.offsetSize).toEqual(0) + }) +}) + +describe('SwipeAction Props', () => { + it('SwipeAction Disabled', () => { const component = renderIntoDocument( - + AtSwipeAction 一般使用场景 ) const componentDom = findDOMNode(component, 'at-swipe-action') + component.maxOffsetSize = MAX_OFFSET_SIZE - const optionDom = componentDom.querySelector('.at-swipe-action__option') + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) - Simulate.click(optionDom) + Simulate.touchMove(componentDom, { + touches: [{ clientX: -110 }] + }) + component.forceUpdate() + expect(component.state.offsetSize).toEqual(0) + }) - expect(onClick).toBeCalled() + it('SwipeAction Disabled', () => { + const component = renderIntoDocument( + + AtSwipeAction 一般使用场景 + + ) + const componentDom = findDOMNode(component, 'at-swipe-action') + component.maxOffsetSize = MAX_OFFSET_SIZE + + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + + Simulate.touchMove(componentDom, { + touches: [{ clientX: -110 }] + }) + component.forceUpdate() + expect(component.state.offsetSize).toEqual(0) + }) + + it('SwipeAction AutoClose', () => { + const component = renderIntoDocument( + + AtSwipeAction 一般使用场景 + + ) + const componentDom = findDOMNode(component, 'at-swipe-action') + const swipeActionButtonDom = componentDom.querySelector( + '.at-swipe-action__option' + ) + component.maxOffsetSize = MAX_OFFSET_SIZE + + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + component.forceUpdate() + + Simulate.touchMove(componentDom, { + touches: [{ clientX: -110 }] + }) + component.forceUpdate() + + Simulate.touchEnd(componentDom) + component.forceUpdate() + + expect(component.state.isOpened).toBeTruthy() + expect(component.state.offsetSize).toEqual(-MAX_OFFSET_SIZE) + + Simulate.click(swipeActionButtonDom) + component.forceUpdate() + + expect(component.endValue).toEqual(0) + expect(component.isTouching).toBeFalsy() + expect(component.state.isOpened).toBeFalsy() + expect(component.state.offsetSize).toEqual(0) + }) + + it('SwipeAction IsClose', () => { + const component = renderIntoDocument( + + AtSwipeAction 一般使用场景 + + ) + const componentDom = findDOMNode(component, 'at-swipe-action') + component.maxOffsetSize = MAX_OFFSET_SIZE + + Simulate.touchStart(componentDom, { + touches: [{ clientX: 0 }] + }) + component.forceUpdate() + + Simulate.touchMove(componentDom, { + touches: [{ clientX: -110 }] + }) + component.forceUpdate() + + Simulate.touchEnd(componentDom) + component.forceUpdate() + + expect(component.state.isOpened).toBeTruthy() + expect(component.state.offsetSize).toEqual(-MAX_OFFSET_SIZE) + + const spy = jest + .spyOn(component, 'componentWillReceiveProps') + .bind(component) + spy({ isClose: true }) + + component.forceUpdate() + + expect(component.state.isOpened).toBeFalsy() }) }) diff --git a/src/components/tabs/__snapshots__/index.test.js.snap b/src/components/tabs/__snapshots__/index.test.js.snap index be854e9ce..90d678be6 100644 --- a/src/components/tabs/__snapshots__/index.test.js.snap +++ b/src/components/tabs/__snapshots__/index.test.js.snap @@ -10,6 +10,8 @@ exports[`AtTabs Snap render AtTabs -- props current 1`] = `"
"`; +exports[`AtTabs Snap render AtTabs -- props height 1`] = `"
标签页1
标签页2
标签页3
"`; + exports[`AtTabs Snap render AtTabs -- props scroll 1`] = `"
标签页1
标签页2
标签页3
"`; exports[`AtTabs Snap render AtTabs -- props swipeable 1`] = `"
标签页1
标签页2
标签页3
"`;