Browse Source

test(sticky): add sticky component test

suzigang 3 years ago
parent
commit
732cfbc514

+ 13 - 0
src/packages/__VUE/sticky/__tests__/__snapshots__/index.spec.ts.snap

@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should sticky to bottom after scroll 1`] = `
+"<view>
+  <view class=\\"nut-sticky\\"></view>
+</view>"
+`;
+
+exports[`should sticky to top after scroll 1`] = `
+"<view>
+  <view class=\\"nut-sticky\\"></view>
+</view>"
+`;

+ 51 - 0
src/packages/__VUE/sticky/__tests__/index.spec.ts

@@ -0,0 +1,51 @@
+import { mount, config, VueWrapper } from '@vue/test-utils';
+import { trigger, mockScrollTop } from './../../../utils/unit';
+import Sticky from '../index.vue';
+import type { ComponentPublicInstance } from 'vue';
+import NutButton from '../../button/index.vue';
+
+beforeAll(() => {
+  config.global.components = {
+    NutButton
+  };
+});
+
+afterAll(() => {
+  config.global.components = {};
+});
+
+Object.defineProperty(window.HTMLElement.prototype, 'clientHeight', {
+  value: 667
+});
+
+function mockStickyRect(wrapper: VueWrapper<ComponentPublicInstance<{}, any>>, rect: Partial<DOMRect>) {
+  const mocked = jest.spyOn(wrapper.element, 'getBoundingClientRect').mockReturnValue(rect as DOMRect);
+
+  return () => mocked.mockRestore();
+}
+
+test('should sticky to top after scroll', async () => {
+  const wrapper = mount(Sticky, {});
+  const restore = mockStickyRect(wrapper, {
+    top: -100,
+    bottom: -90
+  });
+
+  await mockScrollTop(1000);
+  expect(wrapper.html()).toMatchSnapshot();
+
+  restore();
+});
+
+test('should sticky to bottom after scroll', async () => {
+  const wrapper = mount(Sticky);
+  const restore = mockStickyRect(wrapper, {
+    top: 667,
+    bottom: 690
+  });
+
+  await mockScrollTop(0);
+  expect(wrapper.html()).toMatchSnapshot();
+
+  restore();
+});

+ 58 - 0
src/packages/utils/unit.ts

@@ -0,0 +1,58 @@
+import { ComponentPublicInstance, nextTick } from 'vue';
+import { VueWrapper, DOMWrapper } from '@vue/test-utils';
+
+function getTouch(el: Element | Window, x: number, y: number) {
+  return {
+    identifier: Date.now(),
+    target: el,
+    pageX: x,
+    pageY: y,
+    clientX: x,
+    clientY: y,
+    radiusX: 2.5,
+    radiusY: 2.5,
+    rotationAngle: 10,
+    force: 0.5
+  };
+}
+
+export function trigger(
+  wrapper: VueWrapper<ComponentPublicInstance<any, any, any>> | DOMWrapper<Element> | Element | Window,
+  eventName: string,
+  x = 0,
+  y = 0,
+  options: any = {}
+) {
+  const el = 'element' in wrapper ? wrapper.element : wrapper;
+  const touchList = options.touchList || [getTouch(el, x, y)];
+
+  if (options.x || options.y) {
+    touchList.push(getTouch(el, options.x, options.y));
+  }
+
+  const event = document.createEvent('CustomEvent');
+  event.initCustomEvent(eventName, true, true, {});
+
+  Object.assign(event, {
+    clientX: x,
+    clientY: y,
+    touches: touchList,
+    targetTouches: touchList,
+    changedTouches: touchList
+  });
+
+  el.dispatchEvent(event);
+
+  return nextTick();
+}
+export async function mockScrollTop(value: number) {
+  Object.defineProperty(window, 'scrollTop', { value, writable: true });
+  trigger(window, 'scroll');
+  return nextTick();
+}
+
+export function sleep(delay = 0): Promise<void> {
+  return new Promise((resolve) => {
+    setTimeout(resolve, delay);
+  });
+}