139 lines
3.3 KiB
TypeScript
139 lines
3.3 KiB
TypeScript
import React from 'react';
|
|
|
|
import '@testing-library/jest-dom/vitest';
|
|
|
|
import { cleanup } from '@testing-library/react';
|
|
import { afterEach, vi } from 'vitest';
|
|
|
|
Object.defineProperty(globalThis, '__DEV__', {
|
|
configurable: true,
|
|
value: false,
|
|
});
|
|
|
|
const createElement =
|
|
(tag: string) =>
|
|
({
|
|
children,
|
|
onChangeText,
|
|
onPress,
|
|
value,
|
|
...props
|
|
}: {
|
|
children?: React.ReactNode;
|
|
onChangeText?: (value: string) => void;
|
|
onPress?: () => void;
|
|
value?: string;
|
|
[key: string]: unknown;
|
|
}) => {
|
|
const safeProps: Record<string, unknown> = {
|
|
...props,
|
|
className:
|
|
typeof props.className === 'string' ? props.className : undefined,
|
|
disabled: props.disabled as boolean | undefined,
|
|
onChange: onChangeText
|
|
? (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
|
|
onChangeText(event.currentTarget.value)
|
|
: undefined,
|
|
onClick: onPress,
|
|
value,
|
|
};
|
|
delete safeProps.keyboardType;
|
|
delete safeProps.keyboardShouldPersistTaps;
|
|
delete safeProps.placeholderTextColor;
|
|
delete safeProps.secureTextEntry;
|
|
delete safeProps.showsHorizontalScrollIndicator;
|
|
delete safeProps.textAlignVertical;
|
|
|
|
return React.createElement(tag, safeProps, children);
|
|
};
|
|
|
|
const TextInput = ({
|
|
multiline,
|
|
...props
|
|
}: {
|
|
multiline?: boolean;
|
|
[key: string]: unknown;
|
|
}) => createElement(multiline ? 'textarea' : 'input')(props);
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
alert: vi.fn(),
|
|
useAction: vi.fn(() => vi.fn()),
|
|
useMutation: vi.fn(() => vi.fn()),
|
|
useQuery: vi.fn(() => undefined),
|
|
}));
|
|
|
|
vi.mock('react-native', () => ({
|
|
Alert: { alert: mocks.alert },
|
|
Linking: { openURL: vi.fn() },
|
|
Modal: ({
|
|
children,
|
|
visible,
|
|
}: {
|
|
children?: React.ReactNode;
|
|
visible?: boolean;
|
|
}) => (visible ? React.createElement('div', {}, children) : null),
|
|
Pressable: createElement('button'),
|
|
Platform: {
|
|
OS: 'web',
|
|
select: (values: Record<string, unknown>) => values.web ?? values.default,
|
|
},
|
|
RefreshControl: createElement('div'),
|
|
ScrollView: createElement('div'),
|
|
Switch: createElement('input'),
|
|
Text: createElement('span'),
|
|
TextInput,
|
|
TurboModuleRegistry: {
|
|
get: vi.fn(() => undefined),
|
|
getEnforcing: vi.fn(() => ({})),
|
|
},
|
|
View: createElement('div'),
|
|
}));
|
|
|
|
vi.mock('expo-clipboard', () => ({
|
|
setStringAsync: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('expo-haptics', () => ({
|
|
impactAsync: vi.fn(),
|
|
notificationAsync: vi.fn(),
|
|
selectionAsync: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('react-native-safe-area-context', () => ({
|
|
SafeAreaView: createElement('div'),
|
|
}));
|
|
|
|
vi.mock('expo-router', () => ({
|
|
Link: ({ children }: { children?: React.ReactNode }) => children,
|
|
Stack: {
|
|
Screen: () => null,
|
|
},
|
|
useLocalSearchParams: () => ({}),
|
|
useRouter: () => ({
|
|
push: vi.fn(),
|
|
replace: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
vi.mock('convex/react', () => ({
|
|
useAction: mocks.useAction,
|
|
useMutation: mocks.useMutation,
|
|
useQuery: mocks.useQuery,
|
|
}));
|
|
|
|
vi.mock('@convex-dev/auth/react', () => ({
|
|
useAuthActions: () => ({
|
|
signIn: vi.fn(),
|
|
signOut: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
export const mockedAlert = mocks.alert;
|
|
export const mockedUseAction = mocks.useAction;
|
|
export const mockedUseMutation = mocks.useMutation;
|
|
export const mockedUseQuery = mocks.useQuery;
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
});
|