diff --git a/.github/workflow-scripts/__tests__/publishTemplate-test.js b/.github/workflow-scripts/__tests__/publishTemplate-test.js index 9f735a633977..25734752cf4c 100644 --- a/.github/workflow-scripts/__tests__/publishTemplate-test.js +++ b/.github/workflow-scripts/__tests__/publishTemplate-test.js @@ -7,11 +7,6 @@ * @format */ -const { - publishTemplate, - verifyPublishedTemplate, -} = require('../publishTemplate'); - const mockRun = jest.fn(); const mockSleep = jest.fn(); const mockGetNpmPackageInfo = jest.fn(); @@ -29,6 +24,11 @@ jest.mock('../verifyPublishedPackage.js', () => ({ verifyPublishedPackage: mockVerifyPublishedPackage, })); +const { + publishTemplate, + verifyPublishedTemplate, +} = require('../publishTemplate'); + const getMockGithub = () => ({ rest: { actions: { diff --git a/.github/workflow-scripts/__tests__/verifyArtifactsAreOnMaven-test.js b/.github/workflow-scripts/__tests__/verifyArtifactsAreOnMaven-test.js index 8e9758f28609..2216b94d8543 100644 --- a/.github/workflow-scripts/__tests__/verifyArtifactsAreOnMaven-test.js +++ b/.github/workflow-scripts/__tests__/verifyArtifactsAreOnMaven-test.js @@ -7,8 +7,6 @@ * @format */ -const {verifyArtifactsAreOnMaven} = require('../verifyArtifactsAreOnMaven'); - const mockSleep = jest.fn(); const silence = () => {}; const mockFetch = jest.fn(); @@ -19,6 +17,8 @@ jest.mock('../utils.js', () => ({ sleep: mockSleep, })); +const {verifyArtifactsAreOnMaven} = require('../verifyArtifactsAreOnMaven'); + process.exit = mockExit; global.fetch = mockFetch; diff --git a/.github/workflow-scripts/__tests__/verifyPublishedPackage-test.js b/.github/workflow-scripts/__tests__/verifyPublishedPackage-test.js index 95e22baa854e..78c19637e52e 100644 --- a/.github/workflow-scripts/__tests__/verifyPublishedPackage-test.js +++ b/.github/workflow-scripts/__tests__/verifyPublishedPackage-test.js @@ -7,8 +7,6 @@ * @format */ -const {verifyPublishedPackage} = require('../verifyPublishedPackage'); - const mockRun = jest.fn(); const mockSleep = jest.fn(); const mockGetNpmPackageInfo = jest.fn(); @@ -23,6 +21,8 @@ jest.mock('../utils.js', () => ({ getNpmPackageInfo: mockGetNpmPackageInfo, })); +const {verifyPublishedPackage} = require('../verifyPublishedPackage'); + describe('#verifyPublishedPackage', () => { beforeEach(jest.clearAllMocks); diff --git a/.github/workflow-scripts/__tests__/verifyReleaseOnNpm-test.js b/.github/workflow-scripts/__tests__/verifyReleaseOnNpm-test.js index 761c4352b408..e55f126183b5 100644 --- a/.github/workflow-scripts/__tests__/verifyReleaseOnNpm-test.js +++ b/.github/workflow-scripts/__tests__/verifyReleaseOnNpm-test.js @@ -7,8 +7,6 @@ * @format */ -const {verifyReleaseOnNpm} = require('../verifyReleaseOnNpm'); - const mockVerifyPublishedPackage = jest.fn(); const silence = () => {}; @@ -21,6 +19,8 @@ jest.mock('../verifyPublishedPackage.js', () => ({ verifyPublishedPackage: mockVerifyPublishedPackage, })); +const {verifyReleaseOnNpm} = require('../verifyReleaseOnNpm'); + describe('#verifyReleaseOnNPM', () => { beforeEach(jest.clearAllMocks); diff --git a/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js b/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js index dad048f3be18..d85c5581c78a 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js @@ -10,11 +10,33 @@ 'use-strict'; +// The buildSchema tests spy on `getConfigType`, which parsers-commons reads when +// it loads, so it's wrapped before any module that uses it is required. +jest.mock('../utils', () => { + const actual = jest.requireActual('../utils'); + return {...actual, getConfigType: jest.fn(actual.getConfigType)}; +}); + import type {ParserType} from '../errors'; +import typeof * as Utils from '../utils'; -import {FlowParser} from '../flow/parser'; -import {MockedParser} from '../parserMock'; -import { +const { + IncorrectModuleRegistryCallArgumentTypeParserError, + IncorrectModuleRegistryCallArityParserError, + MisnamedModuleInterfaceParserError, + ModuleInterfaceNotFoundParserError, + MoreThanOneModuleInterfaceParserError, + MoreThanOneModuleRegistryCallsParserError, + ParserError, + UnsupportedObjectPropertyTypeAnnotationParserError, + UntypedModuleRegistryCallParserError, + UnusedModuleInterfaceParserError, +} = require('../errors'); +const {buildComponentSchema} = require('../flow/components'); +const {flowTranslateTypeAnnotation} = require('../flow/modules/index'); +const {FlowParser} = require('../flow/parser'); +const {MockedParser} = require('../parserMock'); +const { assertGenericTypeAnnotationHasExactlyOneTypeParameter, buildSchema, buildSchemaFromConfigType, @@ -30,22 +52,7 @@ import { propertyNames, unwrapNullable, wrapNullable, -} from '../parsers-commons'; - -const { - IncorrectModuleRegistryCallArgumentTypeParserError, - IncorrectModuleRegistryCallArityParserError, - MisnamedModuleInterfaceParserError, - ModuleInterfaceNotFoundParserError, - MoreThanOneModuleInterfaceParserError, - MoreThanOneModuleRegistryCallsParserError, - ParserError, - UnsupportedObjectPropertyTypeAnnotationParserError, - UntypedModuleRegistryCallParserError, - UnusedModuleInterfaceParserError, -} = require('../errors'); -const {buildComponentSchema} = require('../flow/components'); -const {flowTranslateTypeAnnotation} = require('../flow/modules/index'); +} = require('../parsers-commons'); const {buildModuleSchema} = require('../parsers-commons.js'); const {Visitor} = require('../parsers-primitives'); const {wrapComponentSchema} = require('../schema.js'); @@ -665,7 +672,7 @@ describe('buildSchemaFromConfigType', () => { }); describe('buildSchema', () => { - const getConfigTypeSpy = jest.spyOn(require('../utils'), 'getConfigType'); + const getConfigTypeSpy = require('../utils').getConfigType; describe('when there is no codegenNativeComponent and no TurboModule', () => { const contents = ''; diff --git a/packages/react-native/Libraries/Animated/__tests__/Animated-test.js b/packages/react-native/Libraries/Animated/__tests__/Animated-test.js index 3d4b8c70fdc7..8e7aa3f02c5a 100644 --- a/packages/react-native/Libraries/Animated/__tests__/Animated-test.js +++ b/packages/react-native/Libraries/Animated/__tests__/Animated-test.js @@ -12,13 +12,13 @@ import * as React from 'react'; const {PlatformColor} = require('../../StyleSheet/PlatformColorValueTypes'); let Animated = require('../Animated').default; -const AnimatedProps = require('../nodes/AnimatedProps').default; -const { +let AnimatedProps = require('../nodes/AnimatedProps').default; +let { create, unmount, update, } = require('@react-native/jest-preset/jest/renderer'); -const TestRenderer = require('react-test-renderer'); +let TestRenderer = require('react-test-renderer'); // WORKAROUND: `jest.runAllTicks` skips tasks scheduled w/ `queueMicrotask`. function mockQueueMicrotask() { @@ -37,6 +37,16 @@ function mockQueueMicrotask() { describe('Animated', () => { beforeEach(() => { jest.resetModules(); + // Reload after the reset, so that Animated and the renderer share a copy + // of React. + Animated = require('../Animated').default; + AnimatedProps = require('../nodes/AnimatedProps').default; + ({ + create, + unmount, + update, + } = require('@react-native/jest-preset/jest/renderer')); + TestRenderer = require('react-test-renderer'); }); mockQueueMicrotask(); diff --git a/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js b/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js index 89a9366e1b59..cd1601713a05 100644 --- a/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js +++ b/packages/react-native/Libraries/LogBox/__tests__/LogBoxInspectorContainer-test.js @@ -10,15 +10,6 @@ 'use strict'; -const BackHandler: $FlowFixMe = require('../../Utilities/BackHandler').default; -const LogBoxData = require('../Data/LogBoxData'); -const LogBoxLog = require('../Data/LogBoxLog').default; -const { - _LogBoxInspectorContainer: LogBoxInspectorContainer, -} = require('../LogBoxInspectorContainer'); -const render = require('@react-native/jest-preset/jest/renderer'); -const React = require('react'); - // Mock `LogBoxInspector` because we are interested in snapshotting the behavior // of `LogBoxInspectorContainer`, not `LogBoxInspector`. jest.mock('../UI/LogBoxInspector', () => ({ @@ -30,6 +21,15 @@ jest.mock('../../Utilities/BackHandler', () => require('../../Utilities/__mocks__/BackHandler'), ); +const BackHandler: $FlowFixMe = require('../../Utilities/BackHandler').default; +const LogBoxData = require('../Data/LogBoxData'); +const LogBoxLog = require('../Data/LogBoxLog').default; +const { + _LogBoxInspectorContainer: LogBoxInspectorContainer, +} = require('../LogBoxInspectorContainer'); +const render = require('@react-native/jest-preset/jest/renderer'); +const React = require('react'); + describe('LogBoxInspectorContainer', () => { let output; diff --git a/packages/react-native/Libraries/LogBox/__tests__/LogBoxNotificationContainer-test.js b/packages/react-native/Libraries/LogBox/__tests__/LogBoxNotificationContainer-test.js index 16d3292fa2bb..343331d4fb9e 100644 --- a/packages/react-native/Libraries/LogBox/__tests__/LogBoxNotificationContainer-test.js +++ b/packages/react-native/Libraries/LogBox/__tests__/LogBoxNotificationContainer-test.js @@ -10,13 +10,6 @@ 'use strict'; -const BackHandler: $FlowFixMe = require('../../Utilities/BackHandler').default; -const LogBoxData = require('../Data/LogBoxData'); -const LogBoxLog = require('../Data/LogBoxLog').default; -const {LogBoxNotificationContainer} = require('../LogBoxNotificationContainer'); -const render = require('@react-native/jest-preset/jest/renderer'); -const React = require('react'); - // Mock `LogBoxLogNotification` because we are interested in snapshotting the // behavior of `LogBoxNotificationContainer`, not `LogBoxLogNotification`. jest.mock('../UI/LogBoxNotification', () => ({ @@ -28,6 +21,13 @@ jest.mock('../../Utilities/BackHandler', () => require('../../Utilities/__mocks__/BackHandler'), ); +const BackHandler: $FlowFixMe = require('../../Utilities/BackHandler').default; +const LogBoxData = require('../Data/LogBoxData'); +const LogBoxLog = require('../Data/LogBoxLog').default; +const {LogBoxNotificationContainer} = require('../LogBoxNotificationContainer'); +const render = require('@react-native/jest-preset/jest/renderer'); +const React = require('react'); + describe('LogBoxNotificationContainer', () => { let output; diff --git a/packages/react-native/scripts/ios-prebuild/__tests__/headers-xcframework-test.js b/packages/react-native/scripts/ios-prebuild/__tests__/headers-xcframework-test.js index b9492192a081..7a902be56f2c 100644 --- a/packages/react-native/scripts/ios-prebuild/__tests__/headers-xcframework-test.js +++ b/packages/react-native/scripts/ios-prebuild/__tests__/headers-xcframework-test.js @@ -10,11 +10,18 @@ 'use strict'; +// headers-xcframework reads `execFileSync` when it loads, so it's mocked before +// the module is required. +const mockExecFileSync = jest.fn(); +jest.mock('node:child_process', () => ({ + ...jest.requireActual('node:child_process'), + execFileSync: mockExecFileSync, +})); + const { buildDepsHeadersXcframework, stubSlicesFromXcframework, } = require('../headers-xcframework'); -const childProcess = require('node:child_process'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); @@ -67,9 +74,9 @@ describe('stubSlicesFromXcframework', () => { // SupportedPlatform/Variant -> key mapping and the unknown-slice guard can be // tested without a real xcframework or macOS tooling. const mockPlist = (obj /*: unknown */) => - jest - .spyOn(childProcess, 'execFileSync') - .mockReturnValue(Buffer.from(JSON.stringify(obj) ?? '', 'utf8')); + mockExecFileSync.mockReturnValue( + Buffer.from(JSON.stringify(obj) ?? '', 'utf8'), + ); afterEach(() => { jest.restoreAllMocks(); diff --git a/packages/react-native/scripts/swiftpm/__tests__/headers-utils-test.js b/packages/react-native/scripts/swiftpm/__tests__/headers-utils-test.js index cd48b6bc063a..d9a4971ff4c2 100644 --- a/packages/react-native/scripts/swiftpm/__tests__/headers-utils-test.js +++ b/packages/react-native/scripts/swiftpm/__tests__/headers-utils-test.js @@ -10,6 +10,12 @@ 'use strict'; +// Mock all required modules +jest.mock('../utils'); +jest.mock('../headers-mappings'); +jest.mock('node:fs'); +jest.mock('node:path'); + const { symlinkCodegenHeaders, symlinkHeadersFromPath, @@ -18,12 +24,6 @@ const { symlinkThirdPartyDependenciesHeaders, } = require('../headers-utils'); -// Mock all required modules -jest.mock('../utils'); -jest.mock('../headers-mappings'); -jest.mock('node:fs'); -jest.mock('node:path'); - describe('symlinkHeadersFromPath', () => { let mockUtils; let mockFs; diff --git a/packages/react-native/scripts/swiftpm/__tests__/prepare-app-utils-test.js b/packages/react-native/scripts/swiftpm/__tests__/prepare-app-utils-test.js index c4cb0f884101..285695a9f7e0 100644 --- a/packages/react-native/scripts/swiftpm/__tests__/prepare-app-utils-test.js +++ b/packages/react-native/scripts/swiftpm/__tests__/prepare-app-utils-test.js @@ -10,17 +10,6 @@ 'use strict'; -const { - configureAppForSwift, - createHardlinks, - findXcodeProjectDirectory, - generateCodegenArtifacts, - prepareHeaders, - runIosPrebuild, - runPodDeintegrate, - setBuildFromSource, -} = require('../prepare-app-utils'); - // Mock child_process module jest.mock('node:child_process'); @@ -33,8 +22,11 @@ jest.mock('../headers-utils'); // Mock prepare-app-dependencies-headers module jest.mock('../prepare-app-dependencies-headers'); -// Mock codegen executor module -jest.mock('../../codegen/generate-artifacts-executor'); +// Mock codegen executor module. Automocking loads the real module, which reads +// package.json through the mocked `fs`. +jest.mock('../../codegen/generate-artifacts-executor', () => ({ + execute: jest.fn(), +})); // Mock path module for absolute paths jest.mock('node:path', () => { @@ -46,6 +38,17 @@ jest.mock('node:path', () => { }; }); +const { + configureAppForSwift, + createHardlinks, + findXcodeProjectDirectory, + generateCodegenArtifacts, + prepareHeaders, + runIosPrebuild, + runPodDeintegrate, + setBuildFromSource, +} = require('../prepare-app-utils'); + describe('createHardlinks', () => { let mockSymlinkReactNativeHeaders; let mockSymlinkThirdPartyDependenciesHeaders; diff --git a/scripts/releases-ci/__tests__/publish-npm-test.js b/scripts/releases-ci/__tests__/publish-npm-test.js index de37e4c92939..83d788099a24 100644 --- a/scripts/releases-ci/__tests__/publish-npm-test.js +++ b/scripts/releases-ci/__tests__/publish-npm-test.js @@ -23,10 +23,16 @@ const getPackagesMock = jest.fn(); const updateHermesVersionsToPrebuiltMock = jest.fn(); const getBranchName = jest.fn(); +import type {BuildType} from '../../releases/utils/version-utils'; + const {REPO_ROOT} = require('../../shared/consts'); -const {publishNpm} = require('../publish-npm'); const path = require('node:path'); +// Required on each call, so that publish-npm picks up the mocks and module +// registry that each test sets up after this file loads. +const publishNpm = (buildType: BuildType): Promise => + require('../publish-npm').publishNpm(buildType); + let consoleLog; describe('publish-npm', () => { diff --git a/scripts/releases-ci/__tests__/publish-updated-packages-test.js b/scripts/releases-ci/__tests__/publish-updated-packages-test.js index 76e721789881..78275ec5ef93 100644 --- a/scripts/releases-ci/__tests__/publish-updated-packages-test.js +++ b/scripts/releases-ci/__tests__/publish-updated-packages-test.js @@ -8,11 +8,6 @@ * @format */ -const { - getTagsFromCommitMessage, - publishUpdatedPackages, -} = require('../publish-updated-packages'); - const getPackagesMock = jest.fn(); const execSync = jest.fn(); const execMock = jest.fn(); @@ -23,6 +18,11 @@ jest.mock('shelljs', () => ({exec: execMock})); jest.mock('../../shared/monorepoUtils', () => ({ getPackages: getPackagesMock, })); + +const { + getTagsFromCommitMessage, + publishUpdatedPackages, +} = require('../publish-updated-packages'); // $FlowFixMe[cannot-write] global.fetch = fetchMock; diff --git a/scripts/releases/__tests__/upload-release-assets-for-dotslash-test.js b/scripts/releases/__tests__/upload-release-assets-for-dotslash-test.js index cf125a11de8e..6f9cf680e0d1 100644 --- a/scripts/releases/__tests__/upload-release-assets-for-dotslash-test.js +++ b/scripts/releases/__tests__/upload-release-assets-for-dotslash-test.js @@ -10,6 +10,10 @@ 'use strict'; +// @octokit/rest is ESM-only, which Jest can't load, and these tests pass their +// own client. +jest.mock('@octokit/rest', () => ({Octokit: jest.fn()})); + const { getReleaseAssetMap, uploadReleaseAssetsForDotSlashFile, diff --git a/scripts/releases/utils/__tests__/npm-utils-test.js b/scripts/releases/utils/__tests__/npm-utils-test.js index 2ece11afa4fd..b3e43d69fe94 100644 --- a/scripts/releases/utils/__tests__/npm-utils-test.js +++ b/scripts/releases/utils/__tests__/npm-utils-test.js @@ -8,8 +8,6 @@ * @format */ -const {getNpmInfo, publishPackage} = require('../npm-utils'); - const execMock = jest.fn(); const getCurrentCommitMock = jest.fn(); const exitIfNotOnGitMock = jest.fn(); @@ -23,6 +21,8 @@ jest.mock('./../scm-utils', () => ({ exitIfNotOnGit: exitIfNotOnGitMock, })); +const {getNpmInfo, publishPackage} = require('../npm-utils'); + describe('npm-utils', () => { beforeEach(() => { jest.resetModules(); diff --git a/scripts/releases/utils/__tests__/scm-utils-test.js b/scripts/releases/utils/__tests__/scm-utils-test.js index 250d8a84b36c..f17b40714fb1 100644 --- a/scripts/releases/utils/__tests__/scm-utils-test.js +++ b/scripts/releases/utils/__tests__/scm-utils-test.js @@ -8,8 +8,6 @@ * @format */ -const {isTaggedLatest} = require('../scm-utils'); - let execResult = null; jest @@ -37,6 +35,8 @@ jest ), })); +const {isTaggedLatest} = require('../scm-utils'); + describe('scm-utils', () => { beforeEach(() => { jest.resetModules();