Skip to content

Commit

Permalink
Move fabric setup to a separate file (#33818)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #33818

This Diff moves the fabric setup from the `react_native_pods` script to its own `fabric` file.

It also introduces tests for the file and some test utilities.

## Changelog
[iOS][Changed] - Move fabric setup to its own file

Reviewed By: cortinico, dmitryrykun

Differential Revision: D36344911

fbshipit-source-id: 586186684be2c0080f247390f26145f2defa9e97
  • Loading branch information
Riccardo Cipolleschi authored and facebook-github-bot committed May 18, 2022
1 parent 2f491bf commit 8a8c33a
Show file tree
Hide file tree
Showing 12 changed files with 613 additions and 62 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"scripts/react_native_pods_utils/script_phases.rb",
"scripts/react_native_pods_utils/script_phases.sh",
"scripts/react_native_pods.rb",
"scripts/cocoapods/codegen.rb",
"scripts/cocoapods/fabric.rb",
"scripts/cocoapods/flipper.rb",
"scripts/react-native-xcode.sh",
"sdks/hermes-engine",
Expand Down
185 changes: 185 additions & 0 deletions scripts/cocoapods/__tests__/codegen-test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# 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"

class CodegenTests < Test::Unit::TestCase
:third_party_provider_header
:third_party_provider_implementation
:base_path
:prefix
:tmp_schema_list_file

def setup
File.enable_testing_mode!
Dir.enable_testing_mode!
Pod::Config.reset()

@prefix = "../.."
@third_party_provider_header = "RCTThirdPartyFabricComponentsProvider.h"
@third_party_provider_implementation = "RCTThirdPartyFabricComponentsProvider.cpp"
@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()
File.reset()
Dir.reset()
end

# ============================================== #
# Test - setup_fabric #
# ============================================== #
def testCheckAndGenerateEmptyThirdPartyProvider_whenFileAlreadyExists_doNothing()

# Arrange
File.mocked_existing_files([
@base_path + "/build/" + @third_party_provider_header,
@base_path + "/build/" + @third_party_provider_implementation,
])

# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')

# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(File.exist_invocation_params, [
@base_path + "/build/" + @third_party_provider_header,
@base_path + "/build/" + @third_party_provider_implementation,
])
assert_equal(Dir.exist_invocation_params, [])
assert_equal(Pod::UI.collected_messages, [])
assert_equal($collected_commands, [])
assert_equal(File.open_files.length, 0)
assert_equal(Pod::Executable.executed_commands.length, 0)
end

def testCheckAndGenerateEmptyThirdPartyProvider_whenHeaderMissingAndCodegenMissing_raiseError()

# Arrange
File.mocked_existing_files([
@base_path + "/build/" + @third_party_provider_implementation,
])

# Act
assert_raise {
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')
}

# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(File.exist_invocation_params, [
@base_path + "/build/" + @third_party_provider_header
])
assert_equal(Dir.exist_invocation_params, [
@base_path + "/"+ @prefix + "/packages/react-native-codegen",
@base_path + "/"+ @prefix + "/../react-native-codegen",
])
assert_equal(Pod::UI.collected_messages, [])
assert_equal($collected_commands, [])
assert_equal(File.open_files.length, 0)
assert_equal(Pod::Executable.executed_commands.length, 0)
end

def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCodegenrepoExists_dontBuildCodegen()

# Arrange
File.mocked_existing_files([
@base_path + "/build/" + @third_party_provider_header,
@base_path + "/build/tmpSchemaList.txt"
])

Dir.mocked_existing_dirs([
@base_path + "/"+ @prefix + "/packages/react-native-codegen",
@base_path + "/"+ @prefix + "/packages/react-native-codegen/lib"
])

# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')

# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(File.exist_invocation_params, [
@base_path + "/build/" + @third_party_provider_header,
@base_path + "/build/" + @third_party_provider_implementation,
@base_path + "/build/tmpSchemaList.txt",
])
assert_equal(Dir.exist_invocation_params, [
@base_path + "/"+ @prefix + "/packages/react-native-codegen",
@base_path + "/"+ @prefix + "/packages/react-native-codegen/lib",
])
assert_equal(Pod::UI.collected_messages, ["[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"])
assert_equal($collected_commands, [])
assert_equal(File.open_invocation_count, 1)
assert_equal(File.open_files_with_mode[@base_path + "/build/tmpSchemaList.txt"], 'w')
assert_equal(File.open_files[0].collected_write, ["[]"])
assert_equal(File.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 + "/build/tmpSchemaList.txt",
"--outputDir", @base_path + "/build"
]
})
assert_equal(File.delete_invocation_count, 1)
assert_equal(File.deleted_files, [@base_path + "/build/tmpSchemaList.txt"])
end

def testCheckAndGenerateEmptyThirdPartyProvider_whenBothMissing_buildCodegen()
# Arrange
codegen_cli_path = @base_path + "/" + @prefix + "/../react-native-codegen"
Dir.mocked_existing_dirs([
codegen_cli_path,
])
# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')

# Assert
assert_equal(Pathname.pwd_invocation_count, 1)
assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1)
assert_equal(File.exist_invocation_params, [
@base_path + "/build/" + @third_party_provider_header,
@base_path + "/build/" + @tmp_schema_list_file
])
assert_equal(Dir.exist_invocation_params, [
@base_path + "/" + @prefix + "/packages/react-native-codegen",
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(File.open_files[0].collected_write, ["[]"])
assert_equal(File.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 + "/build/" + @tmp_schema_list_file,
"--outputDir", @base_path + "/build"
]
})
end
end
49 changes: 49 additions & 0 deletions scripts/cocoapods/__tests__/fabric-test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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 "../fabric.rb"
require_relative "./test_utils/podSpy.rb"

class FabricTest < Test::Unit::TestCase

def setup
podSpy_cleanUp()
end

def test_setupFabric_installsPods
# Arrange
prefix = "../.."

# Act
setup_fabric!(prefix)

# Assert
check_installed_pods(prefix)
end

def check_installed_pods(prefix)
assert_equal($podInvocationCount, 6)

check_pod("React-Fabric", :path => "#{prefix}/ReactCommon")
check_pod("React-rncore", :path => "#{prefix}/ReactCommon")
check_pod("React-graphics", :path => "#{prefix}/ReactCommon/react/renderer/graphics")
check_pod("React-jsi/Fabric", :path => "#{prefix}/ReactCommon/jsi")
check_pod("React-RCTFabric", :path => "#{prefix}/React", :modular_headers => true)
check_pod("RCT-Folly/Fabric", :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec")
end

def check_pod(name, path: nil, modular_headers: nil, podspec: nil)
params = $podInvocation[name]
expected_params = {}

if path != nil then expected_params[:path] = path end
if modular_headers != nil then expected_params[:modular_headers] = modular_headers end
if podspec != nil then expected_params[:podspec] = podspec end

assert_equal(params, expected_params)
end

end
47 changes: 47 additions & 0 deletions scripts/cocoapods/__tests__/test_utils/DirMock.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 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.

class Dir

@@is_testing = false
@@exist_invocation_params = []
@@mocked_existing_dirs = []

# Monkey patched exists? method.
# It is used also by the test runner, so it can't start monkey patched
# To use this, invoke the `is_testing` method before starting your test.
# Remember to invoke `reset` after the test.
def self.exist?(path)
if !@@is_testing
return exists?(path)
end

@@exist_invocation_params.push(path)
return @@mocked_existing_dirs.include?(path)
end

# Getter for the `exist_invocation_params` to check that the exist method
# is invoked with the right parameters
def self.exist_invocation_params()
return @@exist_invocation_params
end

# Set the list of dirs the test must return as existing
def self.mocked_existing_dirs(dirs)
@@mocked_existing_dirs = dirs
end

# Turn on the mocking features of the File mock
def self.enable_testing_mode!()
@@is_testing = true
end

# Resets all the settings for the File mock
def self.reset()
@@mocked_existing_dirs = []
@@is_testing = false
@@exist_invocation_params = []
end
end
Loading

0 comments on commit 8a8c33a

Please sign in to comment.