|
|
@@ -1,254 +1,406 @@
|
|
|
import '@testing-library/jest-dom'
|
|
|
|
|
|
-// Mock Taro Components
|
|
|
-jest.mock('@tarojs/components', () => ({
|
|
|
- View: 'view',
|
|
|
- Text: 'text',
|
|
|
- Input: 'input',
|
|
|
- ScrollView: 'scroll-view',
|
|
|
- Picker: 'picker',
|
|
|
- Image: 'image'
|
|
|
-}))
|
|
|
+/* eslint-disable react/display-name */
|
|
|
|
|
|
-// Mock Taro APIs
|
|
|
-jest.mock('@tarojs/taro', () => ({
|
|
|
- useRouter: () => ({
|
|
|
- params: {}
|
|
|
- }),
|
|
|
- navigateTo: jest.fn(),
|
|
|
- redirectTo: jest.fn(),
|
|
|
- switchTab: jest.fn(),
|
|
|
- reLaunch: jest.fn(),
|
|
|
- navigateBack: jest.fn(),
|
|
|
- showModal: jest.fn(),
|
|
|
- showToast: jest.fn(),
|
|
|
- showLoading: jest.fn(),
|
|
|
- hideLoading: jest.fn(),
|
|
|
- showActionSheet: jest.fn(),
|
|
|
- request: jest.fn(),
|
|
|
- uploadFile: jest.fn(),
|
|
|
- downloadFile: jest.fn(),
|
|
|
- connectSocket: jest.fn(),
|
|
|
- onSocketOpen: jest.fn(),
|
|
|
- onSocketError: jest.fn(),
|
|
|
- onSocketMessage: jest.fn(),
|
|
|
- onSocketClose: jest.fn(),
|
|
|
- sendSocketMessage: jest.fn(),
|
|
|
- closeSocket: jest.fn(),
|
|
|
- chooseImage: jest.fn(),
|
|
|
- previewImage: jest.fn(),
|
|
|
- getImageInfo: jest.fn(),
|
|
|
- saveImageToPhotosAlbum: jest.fn(),
|
|
|
- startRecord: jest.fn(),
|
|
|
- stopRecord: jest.fn(),
|
|
|
- playVoice: jest.fn(),
|
|
|
- pauseVoice: jest.fn(),
|
|
|
- stopVoice: jest.fn(),
|
|
|
- getBackgroundAudioPlayerState: jest.fn(),
|
|
|
- playBackgroundAudio: jest.fn(),
|
|
|
- pauseBackgroundAudio: jest.fn(),
|
|
|
- seekBackgroundAudio: jest.fn(),
|
|
|
- stopBackgroundAudio: jest.fn(),
|
|
|
- onBackgroundAudioPlay: jest.fn(),
|
|
|
- onBackgroundAudioPause: jest.fn(),
|
|
|
- onBackgroundAudioStop: jest.fn(),
|
|
|
- chooseVideo: jest.fn(),
|
|
|
- saveVideoToPhotosAlbum: jest.fn(),
|
|
|
- getLocation: jest.fn(),
|
|
|
- chooseLocation: jest.fn(),
|
|
|
- openLocation: jest.fn(),
|
|
|
- getSystemInfo: jest.fn(),
|
|
|
- getNetworkType: jest.fn(),
|
|
|
- onNetworkStatusChange: jest.fn(),
|
|
|
- onAccelerometerChange: jest.fn(),
|
|
|
- startAccelerometer: jest.fn(),
|
|
|
- stopAccelerometer: jest.fn(),
|
|
|
- onCompassChange: jest.fn(),
|
|
|
- startCompass: jest.fn(),
|
|
|
- stopCompass: jest.fn(),
|
|
|
- makePhoneCall: jest.fn(),
|
|
|
- scanCode: jest.fn(),
|
|
|
- setClipboardData: jest.fn(),
|
|
|
- getClipboardData: jest.fn(),
|
|
|
- openBluetoothAdapter: jest.fn(),
|
|
|
- closeBluetoothAdapter: jest.fn(),
|
|
|
- getBluetoothDevices: jest.fn(),
|
|
|
- getConnectedBluetoothDevices: jest.fn(),
|
|
|
- onBluetoothDeviceFound: jest.fn(),
|
|
|
- onBluetoothAdapterStateChange: jest.fn(),
|
|
|
- createBLEConnection: jest.fn(),
|
|
|
- closeBLEConnection: jest.fn(),
|
|
|
- getBLEDeviceServices: jest.fn(),
|
|
|
- getBLEDeviceCharacteristics: jest.fn(),
|
|
|
- readBLECharacteristicValue: jest.fn(),
|
|
|
- writeBLECharacteristicValue: jest.fn(),
|
|
|
- notifyBLECharacteristicValueChange: jest.fn(),
|
|
|
- onBLEConnectionStateChange: jest.fn(),
|
|
|
- onBLECharacteristicValueChange: jest.fn(),
|
|
|
- startBeaconDiscovery: jest.fn(),
|
|
|
- stopBeaconDiscovery: jest.fn(),
|
|
|
- getBeacons: jest.fn(),
|
|
|
- onBeaconUpdate: jest.fn(),
|
|
|
- onBeaconServiceChange: jest.fn(),
|
|
|
- addPhoneContact: jest.fn(),
|
|
|
- getHCEState: jest.fn(),
|
|
|
- startHCE: jest.fn(),
|
|
|
- stopHCE: jest.fn(),
|
|
|
- onHCEMessage: jest.fn(),
|
|
|
- sendHCEMessage: jest.fn(),
|
|
|
- startWifi: jest.fn(),
|
|
|
- stopWifi: jest.fn(),
|
|
|
- connectWifi: jest.fn(),
|
|
|
- getWifiList: jest.fn(),
|
|
|
- onGetWifiList: jest.fn(),
|
|
|
- setWifiList: jest.fn(),
|
|
|
- onWifiConnected: jest.fn(),
|
|
|
- getConnectedWifi: jest.fn(),
|
|
|
- showShareMenu: jest.fn(),
|
|
|
- hideShareMenu: jest.fn(),
|
|
|
- updateShareMenu: jest.fn(),
|
|
|
- getShareInfo: jest.fn(),
|
|
|
- authCode: jest.fn(),
|
|
|
- login: jest.fn(),
|
|
|
- checkSession: jest.fn(),
|
|
|
- authorize: jest.fn(),
|
|
|
- getUserInfo: jest.fn(),
|
|
|
- requestPayment: jest.fn(),
|
|
|
- showTabBarRedDot: jest.fn(),
|
|
|
- hideTabBarRedDot: jest.fn(),
|
|
|
- showTabBar: jest.fn(),
|
|
|
- hideTabBar: jest.fn(),
|
|
|
- setTabBarBadge: jest.fn(),
|
|
|
- removeTabBarBadge: jest.fn(),
|
|
|
- setTabBarItem: jest.fn(),
|
|
|
- setTabBarStyle: jest.fn(),
|
|
|
- setNavigationBarTitle: jest.fn(),
|
|
|
- setNavigationBarColor: jest.fn(),
|
|
|
- showNavigationBarLoading: jest.fn(),
|
|
|
- hideNavigationBarLoading: jest.fn(),
|
|
|
- setBackgroundColor: jest.fn(),
|
|
|
- setBackgroundTextStyle: jest.fn(),
|
|
|
- showTabBar: jest.fn(),
|
|
|
- hideTabBar: jest.fn(),
|
|
|
- setTabBarStyle: jest.fn(),
|
|
|
- setTabBarItem: jest.fn(),
|
|
|
- showTabBarRedDot: jest.fn(),
|
|
|
- hideTabBarRedDot: jest.fn(),
|
|
|
- setTabBarBadge: jest.fn(),
|
|
|
- removeTabBarBadge: jest.fn(),
|
|
|
- pageScrollTo: jest.fn(),
|
|
|
- startPullDownRefresh: jest.fn(),
|
|
|
- stopPullDownRefresh: jest.fn(),
|
|
|
- createSelectorQuery: jest.fn(),
|
|
|
- createIntersectionObserver: jest.fn(),
|
|
|
- getMenuButtonBoundingClientRect: jest.fn(),
|
|
|
- canvasToTempFilePath: jest.fn(),
|
|
|
- canvasPutImageData: jest.fn(),
|
|
|
- canvasGetImageData: jest.fn(),
|
|
|
- setStorage: jest.fn(),
|
|
|
- getStorage: jest.fn(),
|
|
|
- getStorageInfo: jest.fn(),
|
|
|
- removeStorage: jest.fn(),
|
|
|
- clearStorage: jest.fn(),
|
|
|
- setStorageSync: jest.fn(),
|
|
|
- getStorageSync: jest.fn(),
|
|
|
- getStorageInfoSync: jest.fn(),
|
|
|
- removeStorageSync: jest.fn(),
|
|
|
- clearStorageSync: jest.fn(),
|
|
|
- getSystemInfoSync: jest.fn(),
|
|
|
- getEnv: jest.fn(() => 'h5'),
|
|
|
- ENV_TYPE: {
|
|
|
- WEAPP: 'WEAPP',
|
|
|
- SWAN: 'SWAN',
|
|
|
- ALIPAY: 'ALIPAY',
|
|
|
- TT: 'TT',
|
|
|
- QQ: 'QQ',
|
|
|
- JD: 'JD',
|
|
|
- WEB: 'WEB',
|
|
|
- RN: 'RN',
|
|
|
- HARMONY: 'HARMONY'
|
|
|
+// 设置环境变量
|
|
|
+process.env.TARO_ENV = 'h5'
|
|
|
+process.env.TARO_PLATFORM = 'web'
|
|
|
+process.env.SUPPORT_TARO_POLYFILL = 'disabled'
|
|
|
+
|
|
|
+// Mock Taro 组件
|
|
|
+// eslint-disable-next-line react/display-name
|
|
|
+jest.mock('@tarojs/components', () => {
|
|
|
+ const React = require('react')
|
|
|
+ const MockView = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockView.displayName = 'MockView'
|
|
|
+
|
|
|
+ const MockScrollView = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const {
|
|
|
+ children,
|
|
|
+ onScroll,
|
|
|
+ onTouchStart,
|
|
|
+ onScrollEnd,
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
+ scrollY,
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
+ showScrollbar,
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
+ scrollTop,
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
+ scrollWithAnimation,
|
|
|
+ ...restProps
|
|
|
+ } = props
|
|
|
+ return React.createElement('div', {
|
|
|
+ ...restProps,
|
|
|
+ ref,
|
|
|
+ onScroll: (e: any) => {
|
|
|
+ if (onScroll) onScroll(e)
|
|
|
+ },
|
|
|
+ onTouchStart: (e: any) => {
|
|
|
+ if (onTouchStart) onTouchStart(e)
|
|
|
+ },
|
|
|
+ onTouchEnd: () => {
|
|
|
+ if (onScrollEnd) onScrollEnd()
|
|
|
+ },
|
|
|
+ style: {
|
|
|
+ overflow: 'auto',
|
|
|
+ height: '200px',
|
|
|
+ ...restProps.style
|
|
|
+ }
|
|
|
+ }, children)
|
|
|
+ })
|
|
|
+ MockScrollView.displayName = 'MockScrollView'
|
|
|
+
|
|
|
+ return {
|
|
|
+ View: MockView,
|
|
|
+ ScrollView: MockScrollView,
|
|
|
+ Text: (() => {
|
|
|
+ const MockText = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('span', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockText.displayName = 'MockText'
|
|
|
+ return MockText
|
|
|
+ })(),
|
|
|
+ Button: (() => {
|
|
|
+ const MockButton = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('button', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockButton.displayName = 'MockButton'
|
|
|
+ return MockButton
|
|
|
+ })(),
|
|
|
+ Input: (() => {
|
|
|
+ const MockInput = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('input', { ...restProps, ref })
|
|
|
+ })
|
|
|
+ MockInput.displayName = 'MockInput'
|
|
|
+ return MockInput
|
|
|
+ })(),
|
|
|
+ Textarea: (() => {
|
|
|
+ const MockTextarea = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('textarea', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockTextarea.displayName = 'MockTextarea'
|
|
|
+ return MockTextarea
|
|
|
+ })(),
|
|
|
+ Image: (() => {
|
|
|
+ const MockImage = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('img', { ...restProps, ref })
|
|
|
+ })
|
|
|
+ MockImage.displayName = 'MockImage'
|
|
|
+ return MockImage
|
|
|
+ })(),
|
|
|
+ Form: (() => {
|
|
|
+ const MockForm = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('form', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockForm.displayName = 'MockForm'
|
|
|
+ return MockForm
|
|
|
+ })(),
|
|
|
+ Label: (() => {
|
|
|
+ const MockLabel = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('label', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockLabel.displayName = 'MockLabel'
|
|
|
+ return MockLabel
|
|
|
+ })(),
|
|
|
+ Picker: (() => {
|
|
|
+ const MockPicker = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ MockPicker.displayName = 'MockPicker'
|
|
|
+ return MockPicker
|
|
|
+ })(),
|
|
|
+ Switch: (() => {
|
|
|
+ const MockSwitch = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('input', { type: 'checkbox', ...restProps, ref })
|
|
|
+ })
|
|
|
+ MockSwitch.displayName = 'MockSwitch'
|
|
|
+ return MockSwitch
|
|
|
+ })(),
|
|
|
+ Slider: (() => {
|
|
|
+ const MockSlider = React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('input', { type: 'range', ...restProps, ref })
|
|
|
+ })
|
|
|
+ MockSlider.displayName = 'MockSlider'
|
|
|
+ return MockSlider
|
|
|
+ })(),
|
|
|
+ Radio: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('input', { type: 'radio', ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ RadioGroup: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Checkbox: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('input', { type: 'checkbox', ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ CheckboxGroup: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Progress: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('progress', { ...restProps, ref })
|
|
|
+ }),
|
|
|
+ RichText: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ MovableArea: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ MovableView: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Swiper: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ SwiperItem: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Navigator: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('a', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Audio: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('audio', { ...restProps, ref })
|
|
|
+ }),
|
|
|
+ Video: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('video', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Camera: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ LivePlayer: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ LivePusher: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Map: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Canvas: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('canvas', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ OpenData: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ WebView: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('iframe', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Ad: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ OfficialAccount: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ CoverView: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ CoverImage: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { ...restProps } = props
|
|
|
+ return React.createElement('img', { ...restProps, ref })
|
|
|
+ }),
|
|
|
+ FunctionalPageNavigator: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ AdContent: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ MatchMedia: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ PageContainer: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ ShareElement: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ KeyboardAccessory: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ RootPortal: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ PageMeta: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ NavigationBar: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Block: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Import: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Include: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Template: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Slot: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ NativeSlot: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ CustomWrapper: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ Editor: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ VoipRoom: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ }),
|
|
|
+ AdCustom: React.forwardRef((props: any, ref: any) => {
|
|
|
+ const { children, ...restProps } = props
|
|
|
+ return React.createElement('div', { ...restProps, ref }, children)
|
|
|
+ })
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// 模拟 MutationObserver
|
|
|
+// @ts-ignore
|
|
|
+global.MutationObserver = class {
|
|
|
+ disconnect() {}
|
|
|
+ observe(_element: any, _initObject: any) {}
|
|
|
+ takeRecords() { return [] }
|
|
|
+}
|
|
|
+
|
|
|
+// 模拟 IntersectionObserver
|
|
|
+// @ts-ignore
|
|
|
+global.IntersectionObserver = class {
|
|
|
+ constructor(fn: (args: any[]) => void) {
|
|
|
+ setTimeout(() => {
|
|
|
+ fn([{ isIntersecting: true }])
|
|
|
+ }, 1000)
|
|
|
}
|
|
|
-}))
|
|
|
|
|
|
-// Mock React Query
|
|
|
-jest.mock('@tanstack/react-query', () => ({
|
|
|
- useQuery: jest.fn(() => ({
|
|
|
- data: null,
|
|
|
- isLoading: false,
|
|
|
- error: null
|
|
|
+ observe() {}
|
|
|
+ unobserve() {}
|
|
|
+ disconnect() {}
|
|
|
+ takeRecords() { return [] }
|
|
|
+ root: null = null
|
|
|
+ rootMargin: string = ''
|
|
|
+ thresholds: number[] = []
|
|
|
+}
|
|
|
+
|
|
|
+// 模拟 ResizeObserver
|
|
|
+// @ts-ignore
|
|
|
+global.ResizeObserver = class {
|
|
|
+ observe() {}
|
|
|
+ unobserve() {}
|
|
|
+ disconnect() {}
|
|
|
+}
|
|
|
+
|
|
|
+// 模拟 matchMedia
|
|
|
+Object.defineProperty(window, 'matchMedia', {
|
|
|
+ writable: true,
|
|
|
+ value: jest.fn().mockImplementation(query => ({
|
|
|
+ matches: false,
|
|
|
+ media: query,
|
|
|
+ onchange: null,
|
|
|
+ addListener: jest.fn(), // deprecated
|
|
|
+ removeListener: jest.fn(), // deprecated
|
|
|
+ addEventListener: jest.fn(),
|
|
|
+ removeEventListener: jest.fn(),
|
|
|
+ dispatchEvent: jest.fn(),
|
|
|
})),
|
|
|
- useMutation: jest.fn(() => ({
|
|
|
- mutate: jest.fn(),
|
|
|
- isLoading: false,
|
|
|
- error: null
|
|
|
- }))
|
|
|
-}))
|
|
|
+})
|
|
|
|
|
|
-// Mock API client
|
|
|
-jest.mock('../src/api', () => ({
|
|
|
- areaClient: {
|
|
|
- provinces: {
|
|
|
- $get: jest.fn(() => Promise.resolve({
|
|
|
- status: 200,
|
|
|
- json: () => Promise.resolve([
|
|
|
- { id: 1, name: '北京市', code: '110000' },
|
|
|
- { id: 2, name: '上海市', code: '310000' },
|
|
|
- { id: 3, name: '广东省', code: '440000' }
|
|
|
- ])
|
|
|
- }))
|
|
|
- },
|
|
|
- cities: {
|
|
|
- $get: jest.fn(() => Promise.resolve({
|
|
|
- status: 200,
|
|
|
- json: () => Promise.resolve([
|
|
|
- { id: 1, name: '北京市', code: '110100', provinceId: 1 },
|
|
|
- { id: 2, name: '上海市', code: '310100', provinceId: 2 },
|
|
|
- { id: 3, name: '广州市', code: '440100', provinceId: 3 },
|
|
|
- { id: 4, name: '深圳市', code: '440300', provinceId: 3 }
|
|
|
- ])
|
|
|
- }))
|
|
|
- },
|
|
|
- districts: {
|
|
|
- $get: jest.fn(() => Promise.resolve({
|
|
|
- status: 200,
|
|
|
- json: () => Promise.resolve([
|
|
|
- { id: 1, name: '东城区', code: '110101', cityId: 1 },
|
|
|
- { id: 2, name: '西城区', code: '110102', cityId: 1 },
|
|
|
- { id: 3, name: '天河区', code: '440106', cityId: 3 },
|
|
|
- { id: 4, name: '越秀区', code: '440104', cityId: 3 }
|
|
|
- ])
|
|
|
- }))
|
|
|
- }
|
|
|
- },
|
|
|
- locationClient: {
|
|
|
- $get: jest.fn(() => Promise.resolve({
|
|
|
- status: 200,
|
|
|
- json: () => Promise.resolve({
|
|
|
- data: [
|
|
|
- { id: 1, name: '北京首都国际机场', province: '北京市', city: '北京市', district: '顺义区' },
|
|
|
- { id: 2, name: '北京南站', province: '北京市', city: '北京市', district: '丰台区' },
|
|
|
- { id: 3, name: '上海虹桥机场', province: '上海市', city: '上海市', district: '长宁区' },
|
|
|
- { id: 4, name: '上海火车站', province: '上海市', city: '上海市', district: '静安区' }
|
|
|
- ]
|
|
|
- })
|
|
|
- }))
|
|
|
- },
|
|
|
- routeClient: {
|
|
|
- search: {
|
|
|
- $get: jest.fn(() => Promise.resolve({
|
|
|
- status: 200,
|
|
|
- json: () => Promise.resolve([
|
|
|
- {
|
|
|
- id: 1,
|
|
|
- startLocation: { name: '北京首都国际机场' },
|
|
|
- endLocation: { name: '上海虹桥机场' },
|
|
|
- activities: [
|
|
|
- { id: 1, name: '上海音乐节', startDate: '2025-10-20', venueLocation: { name: '上海音乐厅' } }
|
|
|
- ],
|
|
|
- routeType: 'departure'
|
|
|
- }
|
|
|
- ])
|
|
|
- }))
|
|
|
+// 模拟 getComputedStyle
|
|
|
+Object.defineProperty(window, 'getComputedStyle', {
|
|
|
+ value: () => ({
|
|
|
+ getPropertyValue: (prop: string) => {
|
|
|
+ return {
|
|
|
+ 'font-size': '16px',
|
|
|
+ 'font-family': 'Arial',
|
|
|
+ color: 'rgb(0, 0, 0)',
|
|
|
+ 'background-color': 'rgb(255, 255, 255)',
|
|
|
+ width: '100px',
|
|
|
+ height: '100px',
|
|
|
+ top: '0px',
|
|
|
+ left: '0px',
|
|
|
+ right: '0px',
|
|
|
+ bottom: '0px',
|
|
|
+ x: '0px',
|
|
|
+ y: '0px'
|
|
|
+ }[prop] || ''
|
|
|
}
|
|
|
- }
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+// 模拟 Element.prototype.getBoundingClientRect
|
|
|
+Element.prototype.getBoundingClientRect = jest.fn(() => ({
|
|
|
+ width: 100,
|
|
|
+ height: 100,
|
|
|
+ top: 0,
|
|
|
+ left: 0,
|
|
|
+ bottom: 100,
|
|
|
+ right: 100,
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ toJSON: () => ({
|
|
|
+ width: 100,
|
|
|
+ height: 100,
|
|
|
+ top: 0,
|
|
|
+ left: 0,
|
|
|
+ bottom: 100,
|
|
|
+ right: 100,
|
|
|
+ x: 0,
|
|
|
+ y: 0
|
|
|
+ })
|
|
|
}))
|