From 468b86bd3710b1d43a492c94fb314cc472f03b86 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 8 Jul 2022 07:25:29 -0700 Subject: [PATCH] Move Hermes setup in a dedicated ruby file (#34100) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34100 This Diff continue the effort of refactor and test the cocoapods script, moving hermes setup in a dedicated `hermes.rb` file and adding some tests on the logic of the hermes handling. ## Changelog [iOS][Changed] - move and test Hermes setup from react_native_pods script into a dedicated file Reviewed By: cortinico Differential Revision: D37522432 fbshipit-source-id: 91112476aac576a30110e5dcd4e46fa12241962a --- scripts/cocoapods/__tests__/hermes-test.rb | 85 +++++++++++++++++++ .../__tests__/test_utils/Open3Mock.rb | 43 ++++++++++ .../cocoapods/__tests__/test_utils/PodMock.rb | 29 +++++++ scripts/cocoapods/hermes.rb | 20 +++++ scripts/react_native_pods.rb | 13 +-- 5 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 scripts/cocoapods/__tests__/hermes-test.rb create mode 100644 scripts/cocoapods/__tests__/test_utils/Open3Mock.rb create mode 100644 scripts/cocoapods/hermes.rb diff --git a/scripts/cocoapods/__tests__/hermes-test.rb b/scripts/cocoapods/__tests__/hermes-test.rb new file mode 100644 index 00000000000000..0d22d40a02f687 --- /dev/null +++ b/scripts/cocoapods/__tests__/hermes-test.rb @@ -0,0 +1,85 @@ +# 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 "../hermes.rb" +require_relative "./test_utils/podSpy.rb" +require_relative "./test_utils/PodMock.rb" +require_relative "./test_utils/Open3Mock.rb" + +class HermesTests < Test::Unit::TestCase + + :prefix + + def setup + @prefix = "../.." + end + + def teardown + Open3.reset() + Pod::Config.reset() + Pod::UI.reset() + podSpy_cleanUp() + end + + def test_installHermesIfEnabled_whenHermesIsDisabled_doesNothing + # Arrange + + # Act + install_hermes_if_enabled(false, @prefix) + + # Assert + assert_equal($podInvocationCount, 0) + assert_equal($podInvocation, {}) + assert_equal(Pod::UI.collected_infoes, []) + assert_equal(Open3.collected_commands, []) + assert_equal(Open3.collected_dirs, []) + end + + def test_installHermesIfEnabled_whenHermesIsEnabledAndHermesScriptFails_abort + # Arrange + Pod::Config.instance.installation_root.set_installation_root("Pods/") + Open3.set_returned_status(1) + Open3.set_returned_text("This test\nshould fail") + + # Act + assert_raises { + install_hermes_if_enabled(true, @prefix) + } + + # Assert + assert_equal(Open3.collected_commands, ["node scripts/hermes/prepare-hermes-for-build"]) + assert_equal(Open3.collected_dirs, ["Pods/../.."]) + assert_equal(Pod::UI.collected_infoes, ["This test", "should fail"]) + assert_equal($podInvocationCount, 0) + assert_equal($podInvocation, {}) + end + + def test_installHermesIfEnabled_whenHermesIsEnabledAndHermesScriptSucceeds_installsPods + # Arrange + Pod::Config.instance.installation_root.set_installation_root("Pods/") + Open3.set_returned_status(0) + Open3.set_returned_text("This is\nthe text\nreturned by\nprepare-hermes-for-build") + + # Act + install_hermes_if_enabled(true, @prefix) + + # Assert + assert_equal(Open3.collected_commands, ["node scripts/hermes/prepare-hermes-for-build"]) + assert_equal(Open3.collected_dirs, ["Pods/../.."]) + assert_equal(Pod::UI.collected_infoes, [ + "This is", + "the text", + "returned by", + "prepare-hermes-for-build", + ]) + assert_equal($podInvocationCount, 3) + assert_equal($podInvocation["React-hermes"][:path], "../../ReactCommon/hermes") + assert_equal($podInvocation["libevent"][:version], "~> 2.1.12") + assert_equal($podInvocation["hermes-engine"][:podspec], "../../sdks/hermes/hermes-engine.podspec") + end + + +end diff --git a/scripts/cocoapods/__tests__/test_utils/Open3Mock.rb b/scripts/cocoapods/__tests__/test_utils/Open3Mock.rb new file mode 100644 index 00000000000000..c8a41c6ee6a7af --- /dev/null +++ b/scripts/cocoapods/__tests__/test_utils/Open3Mock.rb @@ -0,0 +1,43 @@ +# 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 Open3 + @@collected_commands = [] + @@collected_dirs = [] + + @@returned_text = "" + @@returned_status = 0 + + def self.capture2e(command, chdir: ".") + @@collected_commands.push(command) + @@collected_dirs.push(chdir) + + return [*@@returned_text, @@returned_status] + end + + def self.collected_commands + return @@collected_commands + end + + def self.collected_dirs + return @@collected_dirs + end + + def self.set_returned_text(text) + @@returned_text = text + end + + def self.set_returned_status(status) + @@returned_status = status + end + + def self.reset() + @@collected_commands = [] + @@collected_dirs = [] + + @@returned_text = "" + @@returned_status = 0 + end +end diff --git a/scripts/cocoapods/__tests__/test_utils/PodMock.rb b/scripts/cocoapods/__tests__/test_utils/PodMock.rb index fcbd46a65e305d..1b2dd1b735e936 100644 --- a/scripts/cocoapods/__tests__/test_utils/PodMock.rb +++ b/scripts/cocoapods/__tests__/test_utils/PodMock.rb @@ -25,21 +25,41 @@ def self.reset() class InstallationRootMock attr_accessor :relative_path_from + attr_accessor :installation_root + attr_reader :relative_path_from_invocation_count + attr_reader :installation_root_invocation_count def initialize() @relative_path_from = "" + @installation_root = "" @relative_path_from_invocation_count = 0 + @installation_root_invocation_count = 0 end def relative_path_from(path) @relative_path_from_invocation_count += 1 return @relative_path_from end + + def installation_root(root) + @installation_root_invocation_count += 1 + return @installation_root + end + + def set_installation_root(root) + @installation_root = root + end + + def join(path) + return @installation_root + path + end + end class UI + @@collected_infoes = [] @@collected_messages = [] @@collected_warns = [] @@ -51,6 +71,10 @@ def self.warn(warn) @@collected_warns.push(warn) end + def self.info(info) + @@collected_infoes.push(info) + end + def self.collected_messages() return @@collected_messages end @@ -59,9 +83,14 @@ def self.collected_warns() return @@collected_warns end + def self.collected_infoes() + return @@collected_infoes + end + def self.reset() @@collected_messages = [] @@collected_warns = [] + @@collected_infoes = [] end end diff --git a/scripts/cocoapods/hermes.rb b/scripts/cocoapods/hermes.rb new file mode 100644 index 00000000000000..747b744c87d7df --- /dev/null +++ b/scripts/cocoapods/hermes.rb @@ -0,0 +1,20 @@ +# 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. + +def install_hermes_if_enabled(hermes_enabled, react_native_path) + unless hermes_enabled + return + end + + prepare_hermes = 'node scripts/hermes/prepare-hermes-for-build' + react_native_dir = Pod::Config.instance.installation_root.join(react_native_path) + prep_output, prep_status = Open3.capture2e(prepare_hermes, :chdir => react_native_dir) + prep_output.split("\n").each { |line| Pod::UI.info line } + abort unless prep_status == 0 + + pod 'React-hermes', :path => "#{react_native_path}/ReactCommon/hermes" + pod 'libevent', '~> 2.1.12' + pod 'hermes-engine', :podspec => "#{react_native_path}/sdks/hermes/hermes-engine.podspec" +end diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index d5457ddc8996d3..3d86c4f3de4e3d 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -7,6 +7,7 @@ require 'open3' require 'pathname' require_relative './react_native_pods_utils/script_phases.rb' +require_relative './cocoapods/hermes.rb' require_relative './cocoapods/flipper.rb' require_relative './cocoapods/fabric.rb' require_relative './cocoapods/codegen.rb' @@ -101,17 +102,7 @@ def use_react_native! (options={}) setup_fabric!(prefix) end - if hermes_enabled - prepare_hermes = 'node scripts/hermes/prepare-hermes-for-build' - react_native_dir = Pod::Config.instance.installation_root.join(prefix) - prep_output, prep_status = Open3.capture2e(prepare_hermes, :chdir => react_native_dir) - prep_output.split("\n").each { |line| Pod::UI.info line } - abort unless prep_status == 0 - - pod 'React-hermes', :path => "#{prefix}/ReactCommon/hermes" - pod 'libevent', '~> 2.1.12' - pod 'hermes-engine', :podspec => "#{prefix}/sdks/hermes/hermes-engine.podspec" - end + install_hermes_if_enabled(hermes_enabled, prefix) # CocoaPods `configurations` option ensures that the target is copied only for the specified configurations, # but those dependencies are still built.