@better-scroll/scroll-bar
Version:
scrollbar is used to BetterScroll, which behaves like browser scrollbar
273 lines (251 loc) • 8.38 kB
text/typescript
import Indicator, { IndicatorDirection, OffsetType } from '../indicator'
import EventHandler from '../event-handler'
import BScroll from '@better-scroll/core'
import { dispatchClick } from '@better-scroll/core/src/__tests__/__utils__/event'
jest.mock('@better-scroll/core')
jest.mock('../event-handler')
const addProperties = <T extends Object, K extends Object>(
target: T,
source: K
) => {
for (const key in source) {
;(target as any)[key] = source[key]
}
return target
}
describe('scroll-bar indicator tests', () => {
let scroll: BScroll
let indicator: Indicator
let wrapper = document.createElement('div')
let indicatorEl = document.createElement('div')
wrapper.appendChild(indicatorEl)
let indicatorOptions = {
wrapper,
direction: IndicatorDirection.Vertical,
fade: true,
fadeInTime: 250,
fadeOutTime: 500,
interactive: false,
minSize: 8,
isCustom: false,
scrollbarTrackClickable: false,
scrollbarTrackOffsetType: OffsetType.Step,
scrollbarTrackOffsetTime: 300,
}
beforeEach(() => {
// create Dom
const wrapper = document.createElement('div')
const content = document.createElement('div')
wrapper.appendChild(content)
scroll = new BScroll(wrapper, {})
})
afterEach(() => {
jest.clearAllMocks()
})
it('should have corrent key', () => {
indicator = new Indicator(scroll, indicatorOptions)
expect(indicator.keysMap).toMatchObject({
hasScroll: 'hasVerticalScroll',
size: 'height',
wrapperSize: 'clientHeight',
scrollerSize: 'scrollerHeight',
maxScrollPos: 'maxScrollY',
pos: 'y',
point: 'pageY',
translateProperty: 'translateY',
domRect: 'top',
})
expect(wrapper.style.opacity).toEqual('0')
})
it('refresh hook', () => {
Object.assign(indicatorOptions, {
direction: IndicatorDirection.Horizontal,
})
indicator = new Indicator(scroll, indicatorOptions)
addProperties(scroll, {
hasHorizontalScroll: true,
maxScrollX: 8,
})
scroll.hooks.trigger(scroll.hooks.eventTypes.refresh)
expect(indicator.currentPos).toBe(-8)
})
it('translate hook', () => {
Object.assign(indicatorOptions, {
direction: IndicatorDirection.Horizontal,
})
indicator = new Indicator(scroll, indicatorOptions)
addProperties(scroll, {
hasHorizontalScroll: true,
maxScrollX: 8,
})
const translaterHooks = scroll.scroller.translater.hooks
scroll.hooks.trigger(scroll.hooks.eventTypes.refresh)
translaterHooks.trigger(translaterHooks.eventTypes.translate, {
x: 10,
y: 0,
})
expect(indicator.currentPos).toBe(0)
})
it('transitionTime and transitionTimingFunction hook', () => {
Object.assign(indicatorOptions, {
direction: IndicatorDirection.Horizontal,
})
indicator = new Indicator(scroll, indicatorOptions)
const animaterHooks = scroll.scroller.animater.hooks
animaterHooks.trigger(animaterHooks.eventTypes.time)
animaterHooks.trigger(
animaterHooks.eventTypes.timeFunction,
'cubic-bezier(0.23, 1, 0.32, 1)'
)
expect(indicator.indicatorEl.style.transitionDuration).toBe('0ms')
expect(indicator.indicatorEl.style.transitionTimingFunction).toBe(
'cubic-bezier(0.23, 1, 0.32, 1)'
)
})
it("about scrolling's hook", () => {
Object.assign(indicatorOptions, {
direction: IndicatorDirection.Horizontal,
})
indicator = new Indicator(scroll, indicatorOptions)
scroll.trigger(scroll.eventTypes.scrollStart)
expect(indicator.wrapper.style.opacity).toBe('1')
scroll.trigger(scroll.eventTypes.scrollEnd)
expect(indicator.wrapper.style.opacity).toBe('0')
})
it("about mouse-wheel scrolling's hook", () => {
Object.assign(indicatorOptions, {
direction: IndicatorDirection.Horizontal,
})
indicator = new Indicator(scroll, indicatorOptions)
scroll.registerType(['mousewheelStart', 'mousewheelMove', 'mousewheelEnd'])
scroll.trigger(scroll.eventTypes.mousewheelStart)
expect(indicator.wrapper.style.opacity).toBe('1')
scroll.trigger(scroll.eventTypes.mousewheelEnd)
expect(indicator.wrapper.style.opacity).toBe('0')
scroll.trigger(scroll.eventTypes.mousewheelMove)
expect(indicator.wrapper.style.opacity).toBe('1')
})
it('interactive option', () => {
// horizontal
addProperties(scroll.options, {
probeType: 3,
})
addProperties(scroll, {
hasHorizontalScroll: true,
maxScrollX: 8,
})
Object.assign(indicatorOptions, {
direction: IndicatorDirection.Horizontal,
interactive: true,
})
indicator = new Indicator(scroll, indicatorOptions)
indicator.refresh()
const beforeStartMockFn = jest.fn()
const startMockFn = jest.fn()
const moveMockFn = jest.fn()
const endMockFn = jest.fn()
const scroller = scroll.scroller
scroller.hooks.on(
scroller.hooks.eventTypes.beforeScrollStart,
beforeStartMockFn
)
scroller.hooks.on(scroller.hooks.eventTypes.scrollStart, startMockFn)
scroller.hooks.on(scroller.hooks.eventTypes.scroll, moveMockFn)
scroller.hooks.on(scroller.hooks.eventTypes.scrollEnd, endMockFn)
const eventHandlerHooks = indicator.eventHandler.hooks
indicator.scrollInfo.maxScrollPos = 10
eventHandlerHooks.trigger(eventHandlerHooks.eventTypes.touchStart)
eventHandlerHooks.trigger(eventHandlerHooks.eventTypes.touchMove, 2)
eventHandlerHooks.trigger(eventHandlerHooks.eventTypes.touchEnd)
expect(beforeStartMockFn).toBeCalled()
expect(startMockFn).toBeCalled()
expect(moveMockFn).toBeCalled()
expect(endMockFn).toBeCalled()
expect(scroll.scroller.translater.translate).toBeCalled()
// vertical
addProperties(scroll.options, {
probeType: 1,
})
addProperties(scroll, {
hasHorizontalScroll: false,
hasVerticalScroll: true,
maxScrollX: 0,
maxScrollY: 8,
})
addProperties(indicator, {
direction: IndicatorDirection.Vertical,
})
eventHandlerHooks.trigger(eventHandlerHooks.eventTypes.touchStart)
indicator.startTime = indicator.startTime - 400
indicator.scrollInfo.maxScrollPos = 10
eventHandlerHooks.trigger(eventHandlerHooks.eventTypes.touchMove, 2)
eventHandlerHooks.trigger(eventHandlerHooks.eventTypes.touchEnd)
expect(beforeStartMockFn).toBeCalledTimes(2)
expect(startMockFn).toBeCalledTimes(2)
expect(moveMockFn).toBeCalledTimes(2)
expect(endMockFn).toBeCalledTimes(2)
expect(scroll.scroller.translater.translate).toBeCalledTimes(2)
})
it('updatePosition', () => {
addProperties(scroll, {
maxScrollY: -8,
})
addProperties(indicatorOptions, {
direction: IndicatorDirection.Vertical,
})
indicator = new Indicator(scroll, indicatorOptions)
indicator.refresh()
indicator.updatePosition({
x: 0,
y: -2,
})
expect(indicator.currentPos).toBe(0)
addProperties(scroll, {
maxScrollY: 8,
})
addProperties(indicator.options, {
isCustom: true,
})
indicator.refresh()
indicator.updatePosition({
x: 0,
y: 2,
})
expect(indicator.currentPos).toBe(0)
})
it('click', () => {
addProperties(scroll, {
maxScrollY: -8,
})
addProperties(indicatorOptions, {
direction: IndicatorDirection.Vertical,
scrollbarTrackClickable: true,
})
indicator = new Indicator(scroll, indicatorOptions)
indicator.refresh()
dispatchClick(indicator.wrapper, 'click')
expect(scroll.scrollTo).toBeCalled()
addProperties(indicator, {
direction: IndicatorDirection.Horizontal,
})
addProperties(indicator.options, {
scrollbarTrackClickable: true,
scrollbarTrackOffsetType: OffsetType.Point,
})
dispatchClick(indicator.wrapper, 'click')
expect(scroll.scrollTo).toBeCalled()
})
it('destroy', () => {
const parentNode = document.createElement('div')
parentNode.appendChild(wrapper)
addProperties(indicatorOptions, {
direction: IndicatorDirection.Vertical,
scrollbarTrackClickable: true,
isCustom: false,
})
indicator = new Indicator(scroll, indicatorOptions)
indicator.destroy()
expect(indicator.eventHandler.destroy).toBeCalled()
expect(indicator.hooksFn.length).toBe(0)
})
})