migrate pure-logic tests to vitest (phase 1)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Stub for expo-application. The real package transitively imports the `expo`
|
||||
* package, whose native winter runtime does bare CJS requires that don't
|
||||
* resolve under Vitest. #/env only reads nativeBuildVersion.
|
||||
*
|
||||
* Aliased in place of expo-application via resolve.alias in vitest.config.ts.
|
||||
*/
|
||||
export const nativeApplicationVersion = '1.0.0'
|
||||
export const nativeBuildVersion = '1'
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Stub for the bare `expo` package. Importing the real entry runs Expo's
|
||||
* "winter" runtime side-effect, which does bare CJS requires (./TextDecoder
|
||||
* etc) that don't resolve under Vitest's node environment. Node already
|
||||
* provides TextDecoder and friends, so we just need the named exports
|
||||
* test-reachable code pulls from `expo`.
|
||||
*
|
||||
* Aliased in place of `expo` via resolve.alias in vitest.config.ts.
|
||||
*/
|
||||
import {vi} from 'vitest'
|
||||
|
||||
export function requireNativeModule(moduleName: string) {
|
||||
if (moduleName === 'ExpoPlatformInfo') {
|
||||
return {getIsReducedMotionEnabled: () => false}
|
||||
}
|
||||
if (moduleName === 'BottomSheet') {
|
||||
return {dismissAll: () => {}}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
export function requireOptionalNativeModule() {
|
||||
return null
|
||||
}
|
||||
|
||||
export const requireNativeView = vi.fn(() => () => null)
|
||||
|
||||
export class NativeModule {}
|
||||
export class SharedObject {}
|
||||
export class SharedRef {}
|
||||
|
||||
export const useEvent = vi.fn()
|
||||
export const useEventListener = vi.fn()
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Stub for @bsky.app/react-native-mmkv. The real package binds to a native
|
||||
* module and imports `react-native`, neither of which works under Vitest's
|
||||
* node environment. Tests that exercise storage logic mock this module's MMKV
|
||||
* with their own in-memory implementation; this stub just provides a class
|
||||
* shape so transitive importers (e.g. #/storage) load without booting RN.
|
||||
*
|
||||
* Aliased in place of @bsky.app/react-native-mmkv via resolve.alias in
|
||||
* vitest.config.ts.
|
||||
*/
|
||||
export class MMKV {
|
||||
getString() {
|
||||
return undefined
|
||||
}
|
||||
set() {}
|
||||
delete() {}
|
||||
getAllKeys(): string[] {
|
||||
return []
|
||||
}
|
||||
clearAll() {}
|
||||
addOnValueChangedListener() {
|
||||
return {remove() {}}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Stub for `react-native` used in unit tests. react-native's real entry is
|
||||
* Flow-typed and boots a native runtime, neither of which works (or is needed)
|
||||
* under Vitest's node environment. This is aliased in place of `react-native`
|
||||
* via resolve.alias in vitest.config.ts.
|
||||
*
|
||||
* Only the surface our test-reachable modules actually touch is implemented:
|
||||
* - Image.getSize (src/lib/media/manip.ts)
|
||||
* - NativeModules / Platform (@bsky.app/react-native-mmkv)
|
||||
* Extend as new transitive usages appear.
|
||||
*/
|
||||
import {vi} from 'vitest'
|
||||
|
||||
export const Image = {getSize: vi.fn()}
|
||||
|
||||
export const NativeModules: Record<string, unknown> = {}
|
||||
|
||||
export const Platform = {
|
||||
OS: 'ios' as const,
|
||||
select: <T>(o: {ios?: T; android?: T; native?: T; default?: T}): T =>
|
||||
(o.ios ?? o.native ?? o.default) as T,
|
||||
}
|
||||
|
||||
export const Dimensions = {
|
||||
get: () => ({width: 390, height: 844, scale: 3, fontScale: 1}),
|
||||
addEventListener: () => ({remove() {}}),
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Stub for @sentry/react-native. The real package is CJS and requires
|
||||
* `react-native` internally, which boots the native runtime under node. Many
|
||||
* test-reachable modules pull it in transitively via #/logger. We only need
|
||||
* the surface sentryTransport touches (src/logger/transports/sentry.ts).
|
||||
*
|
||||
* Aliased in place of @sentry/react-native via resolve.alias in
|
||||
* vitest.config.ts. Tests that assert on Sentry calls (logger.test.ts) still
|
||||
* vi.mock it directly, which takes precedence.
|
||||
*/
|
||||
import {vi} from 'vitest'
|
||||
|
||||
export const addBreadcrumb = vi.fn()
|
||||
export const captureException = vi.fn()
|
||||
export const captureMessage = vi.fn()
|
||||
export const init = vi.fn()
|
||||
+28
-8
@@ -1,16 +1,36 @@
|
||||
import {vi} from 'vitest'
|
||||
|
||||
/*
|
||||
* The only place `react-native` enters the test module graph is a single
|
||||
* transitive import in src/lib/media/manip.ts (`import {Image} from
|
||||
* 'react-native'`). react-native's entry is Flow-typed, which esbuild cannot
|
||||
* parse, so we stub it. manip.ts only touches RNImage.getSize; Platform is
|
||||
* included for any other incidental use.
|
||||
* Note: `react-native` itself is stubbed via resolve.alias in
|
||||
* vitest.config.ts (-> vitest/react-native-stub.ts), not here.
|
||||
*/
|
||||
vi.mock('react-native', () => ({
|
||||
Image: {getSize: vi.fn()},
|
||||
|
||||
/*
|
||||
* expo-modules-core reads its native EventEmitter / NativeModule classes off
|
||||
* globalThis.expo, which only exists in a real Expo runtime. Several utility
|
||||
* modules pull it in transitively (via expo-application, expo-localization,
|
||||
* etc). We only need the handful of helpers tests actually touch.
|
||||
*/
|
||||
vi.mock('expo-modules-core', () => ({
|
||||
requireNativeModule: vi.fn((moduleName: string) => {
|
||||
if (moduleName === 'ExpoPlatformInfo') {
|
||||
return {getIsReducedMotionEnabled: () => false}
|
||||
}
|
||||
if (moduleName === 'BottomSheet') {
|
||||
return {dismissAll: () => {}}
|
||||
}
|
||||
return {}
|
||||
}),
|
||||
requireNativeViewManager: vi.fn(() => () => null),
|
||||
requireOptionalNativeModule: vi.fn(() => null),
|
||||
createPermissionHook: () => () => [true],
|
||||
NativeModule: class {},
|
||||
SharedObject: class {},
|
||||
SharedRef: class {},
|
||||
EventEmitter: class {},
|
||||
Platform: {
|
||||
OS: 'ios',
|
||||
select: (o: Record<string, unknown>) => o.ios ?? o.default,
|
||||
isDOMAvailable: false,
|
||||
select: (o: Record<string, unknown>) => o.ios,
|
||||
},
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user