Files
react-native/packages/react-native/scripts/cocoapods/__tests__/codegen-test.rb
T
Tommy Nguyen dcdea80d9e Fix build_codegen! not finding @react-native/codegen in pnpm setups (#41399)
Summary:
`build_codegen!` currently assumes that `react-native/codegen` gets installed next to `react-native`. In a pnpm setup, it's found under `/~/react-native/node_modules/react-native/codegen` instead.

However, as dmytrorykun pointed out, we don't actually need to build it outside of this repository.

## Changelog:

[GENERAL] [FIXED] - `react-native/codegen` shouldn't be built unless it's in the repo — fixes `pod install` failures in pnpm setups

Pull Request resolved: https://github.com/facebook/react-native/pull/41399

Test Plan: We have a patched version of `react-native` working in a pnpm setup here: https://github.com/microsoft/rnx-kit/pull/2811

Reviewed By: dmytrorykun

Differential Revision: D51201643

Pulled By: cipolleschi

fbshipit-source-id: 53767ae08686a20f03b3b93abcbc7d5383083872
2023-11-27 11:07:30 +00:00

286 lines
12 KiB
Ruby
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
require "test/unit"
require_relative "../codegen.rb"
require_relative "./test_utils/PodMock.rb"
require_relative "./test_utils/PathnameMock.rb"
require_relative "./test_utils/FileMock.rb"
require_relative "./test_utils/DirMock.rb"
require_relative "./test_utils/systemUtils.rb"
require_relative "./test_utils/CodegenUtilsMock.rb"
class CodegenTests < Test::Unit::TestCase
:third_party_provider_header
:third_party_provider_implementation
:base_path
:prefix
:tmp_schema_list_file
def setup
Pod::Config.reset()
@prefix = "../.."
@third_party_provider_header = "RCTThirdPartyFabricComponentsProvider.h"
@third_party_provider_implementation = "RCTThirdPartyFabricComponentsProvider.mm"
@base_path = "~/app/ios"
@tmp_schema_list_file = "tmpSchemaList.txt"
Pathname.pwd!(@base_path)
Pod::Config.instance.installation_root.relative_path_from = @base_path
end
def teardown
system_reset_commands()
Pod::UI.reset()
Pod::Executable.reset()
Pathname.reset()
FileMock.reset()
DirMock.reset()
end
# ============================================== #
# Test - setup_fabric #
# ============================================== #
def testCheckAndGenerateEmptyThirdPartyProvider_whenFileAlreadyExists_doNothing()
# Arrange
FileMock.mocked_existing_files([
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_implementation,
])
# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock)
# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_implementation,
])
assert_equal(DirMock.exist_invocation_params, [])
assert_equal(Pod::UI.collected_messages, [])
assert_equal($collected_commands, [])
assert_equal(FileMock.open_files.length, 0)
assert_equal(Pod::Executable.executed_commands.length, 0)
end
def testCheckAndGenerateEmptyThirdPartyProvider_whenHeaderMissingAndCodegenMissing_dontBuildCodegen()
# Arrange
FileMock.mocked_existing_files([
@base_path + "/build/" + @third_party_provider_implementation,
])
# Act
assert_nothing_raised {
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock)
}
# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt",
])
assert_equal(DirMock.exist_invocation_params, [
@base_path + "/"+ @prefix + "/../react-native-codegen",
])
assert_equal(Pod::UI.collected_messages, [
"[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider",
])
assert_equal($collected_commands, [])
assert_equal(FileMock.open_files.length, 1)
assert_equal(Pod::Executable.executed_commands.length, 1)
end
def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCodegenrepoExists_dontBuildCodegen()
# Arrange
FileMock.mocked_existing_files([
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt"
])
DirMock.mocked_existing_dirs([
@base_path + "/"+ @prefix + "/../react-native-codegen",
@base_path + "/"+ @prefix + "/../react-native-codegen/lib"
])
# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock)
# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_implementation,
@base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt",
])
assert_equal(DirMock.exist_invocation_params, [
@base_path + "/"+ @prefix + "/../react-native-codegen",
@base_path + "/"+ @prefix + "/../react-native-codegen/lib",
])
assert_equal(Pod::UI.collected_messages, ["[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"])
assert_equal($collected_commands, [])
assert_equal(FileMock.open_invocation_count, 1)
assert_equal(FileMock.open_files_with_mode[@prefix + "/React/Fabric/tmpSchemaList.txt"], nil)
assert_equal(FileMock.open_files[0].collected_write, ["[]"])
assert_equal(FileMock.open_files[0].fsync_invocation_count, 1)
assert_equal(Pod::Executable.executed_commands[0], {
"command" => "node",
"arguments" => [
@base_path + "/" + @prefix + "/scripts/generate-provider-cli.js",
"--platform", 'ios',
"--schemaListPath", @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt",
"--outputDir", @base_path + "/" + @prefix + "/React/Fabric"
]
})
assert_equal(FileMock.delete_invocation_count, 1)
assert_equal(FileMock.deleted_files, [ @base_path + "/" + @prefix + "/React/Fabric/tmpSchemaList.txt"])
end
def testCheckAndGenerateEmptyThirdPartyProvider_whenBothMissing_buildCodegen()
# Arrange
codegen_cli_path = @base_path + "/" + @prefix + "/../react-native-codegen"
DirMock.mocked_existing_dirs([
codegen_cli_path,
])
# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, dir_manager: DirMock, file_manager: FileMock)
# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/" + @prefix + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + @prefix + "/React/Fabric/" + @tmp_schema_list_file
])
assert_equal(DirMock.exist_invocation_params, [
codegen_cli_path,
codegen_cli_path + "/lib",
])
assert_equal(Pod::UI.collected_messages, [
"[Codegen] building #{codegen_cli_path}",
"[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"
])
assert_equal($collected_commands, ["~/app/ios/../../../react-native-codegen/scripts/oss/build.sh"])
assert_equal(FileMock.open_files[0].collected_write, ["[]"])
assert_equal(FileMock.open_files[0].fsync_invocation_count, 1)
assert_equal(Pod::Executable.executed_commands[0], {
"command" => "node",
"arguments" => [
@base_path + "/" + @prefix + "/scripts/generate-provider-cli.js",
"--platform", 'ios',
"--schemaListPath", @base_path + "/" + @prefix + "/React/Fabric/" + @tmp_schema_list_file,
"--outputDir", @base_path + "/" + @prefix + "/React/Fabric"
]
})
end
def testCheckAndGenerateEmptyThirdPartyProvider_withAbsoluteReactNativePath_buildCodegen()
# Arrange
rn_path = 'packages/react-native'
codegen_cli_path = rn_path + "/../react-native-codegen"
DirMock.mocked_existing_dirs([
@base_path + "/" + codegen_cli_path,
])
# Act
checkAndGenerateEmptyThirdPartyProvider!(rn_path, false, dir_manager: DirMock, file_manager: FileMock)
# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/" + rn_path + "/React/Fabric/" + @third_party_provider_header,
@base_path + "/" + rn_path + "/React/Fabric/" + @tmp_schema_list_file
])
assert_equal(DirMock.exist_invocation_params, [
@base_path + "/" + codegen_cli_path,
@base_path + "/" + codegen_cli_path + "/lib",
])
assert_equal(Pod::UI.collected_messages, [
"[Codegen] building #{@base_path + "/" + codegen_cli_path}",
"[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"
])
assert_equal($collected_commands, [
@base_path + "/" + rn_path + "/../react-native-codegen/scripts/oss/build.sh",
])
assert_equal(FileMock.open_files[0].collected_write, ["[]"])
assert_equal(FileMock.open_files[0].fsync_invocation_count, 1)
assert_equal(Pod::Executable.executed_commands[0], {
"command" => "node",
"arguments" => [
@base_path + "/" + rn_path + "/scripts/generate-provider-cli.js",
"--platform", 'ios',
"--schemaListPath", @base_path + "/" + rn_path + "/React/Fabric/" + @tmp_schema_list_file,
"--outputDir", @base_path + "/" + rn_path + "/React/Fabric"
]
})
end
# ================= #
# Test - RunCodegen #
# ================= #
def testRunCodegen_whenNewArchEnabled_runsCodegen
# Arrange
app_path = "~/app"
config_file = ""
codegen_utils_mock = CodegenUtilsMock.new()
# Act
run_codegen!(app_path, config_file, :new_arch_enabled => true, :codegen_utils => codegen_utils_mock)
# Assert
assert_equal(codegen_utils_mock.use_react_native_codegen_discovery_params, [{
:app_path=>"~/app",
:codegen_disabled=>false,
:codegen_output_dir=>"build/generated/ios",
:config_file_dir=>"",
:fabric_enabled=>false,
:folly_version=>"2022.05.16.00",
:react_native_path=>"../node_modules/react-native"
}])
assert_equal(codegen_utils_mock.get_react_codegen_spec_params, [])
assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, [])
end
def testRunCodegen_whenNewArchDisabled_runsCodegen
# Arrange
app_path = "~/app"
config_file = ""
package_json_file = "~/app/package.json"
codegen_specs = { "name" => "React-Codegen" }
codegen_utils_mock = CodegenUtilsMock.new(:react_codegen_spec => codegen_specs)
# Act
run_codegen!(
app_path,
config_file,
:new_arch_enabled => false,
:fabric_enabled => true,
:package_json_file => package_json_file,
:codegen_utils => codegen_utils_mock)
# Assert
assert_equal(codegen_utils_mock.use_react_native_codegen_discovery_params, [])
assert_equal(codegen_utils_mock.get_react_codegen_spec_params, [{
:fabric_enabled => true,
:folly_version=>"2022.05.16.00",
:package_json_file => "~/app/package.json",
:script_phases => nil
}])
assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, [{
:codegen_output_dir=>"build/generated/ios",
:react_codegen_spec=>{"name"=>"React-Codegen"}
}])
end
end