1# Copyright (c) Meta Platforms, Inc. and affiliates. 2# 3# This source code is licensed under the MIT license found in the 4# LICENSE file in the root directory of this source tree. 5 6require "test/unit" 7require_relative "../codegen.rb" 8require_relative "./test_utils/PodMock.rb" 9require_relative "./test_utils/PathnameMock.rb" 10require_relative "./test_utils/FileMock.rb" 11require_relative "./test_utils/DirMock.rb" 12require_relative "./test_utils/systemUtils.rb" 13require_relative "./test_utils/CodegenUtilsMock.rb" 14 15class CodegenTests < Test::Unit::TestCase 16 :third_party_provider_header 17 :third_party_provider_implementation 18 :base_path 19 :prefix 20 :tmp_schema_list_file 21 22 def setup 23 File.enable_testing_mode! 24 Dir.enable_testing_mode! 25 Pod::Config.reset() 26 27 @prefix = "../.." 28 @third_party_provider_header = "RCTThirdPartyFabricComponentsProvider.h" 29 @third_party_provider_implementation = "RCTThirdPartyFabricComponentsProvider.cpp" 30 @base_path = "~/app/ios" 31 @tmp_schema_list_file = "tmpSchemaList.txt" 32 Pathname.pwd!(@base_path) 33 Pod::Config.instance.installation_root.relative_path_from = @base_path 34 end 35 36 def teardown 37 system_reset_commands() 38 Pod::UI.reset() 39 Pod::Executable.reset() 40 Pathname.reset() 41 File.reset() 42 Dir.reset() 43 end 44 45 # ============================================== # 46 # Test - setup_fabric # 47 # ============================================== # 48 def testCheckAndGenerateEmptyThirdPartyProvider_whenFileAlreadyExists_doNothing() 49 50 # Arrange 51 File.mocked_existing_files([ 52 @base_path + "/build/" + @third_party_provider_header, 53 @base_path + "/build/" + @third_party_provider_implementation, 54 ]) 55 56 # Act 57 checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') 58 59 # Assert 60 assert_equal(Pathname.pwd_invocation_count, 1) 61 assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) 62 assert_equal(File.exist_invocation_params, [ 63 @base_path + "/build/" + @third_party_provider_header, 64 @base_path + "/build/" + @third_party_provider_implementation, 65 ]) 66 assert_equal(Dir.exist_invocation_params, []) 67 assert_equal(Pod::UI.collected_messages, []) 68 assert_equal($collected_commands, []) 69 assert_equal(File.open_files.length, 0) 70 assert_equal(Pod::Executable.executed_commands.length, 0) 71 end 72 73 def testCheckAndGenerateEmptyThirdPartyProvider_whenHeaderMissingAndCodegenMissing_raiseError() 74 75 # Arrange 76 File.mocked_existing_files([ 77 @base_path + "/build/" + @third_party_provider_implementation, 78 ]) 79 80 # Act 81 assert_raise { 82 checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') 83 } 84 85 # Assert 86 assert_equal(Pathname.pwd_invocation_count, 1) 87 assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) 88 assert_equal(File.exist_invocation_params, [ 89 @base_path + "/build/" + @third_party_provider_header 90 ]) 91 assert_equal(Dir.exist_invocation_params, [ 92 @base_path + "/"+ @prefix + "/packages/react-native-codegen", 93 @base_path + "/"+ @prefix + "/../react-native-codegen", 94 ]) 95 assert_equal(Pod::UI.collected_messages, []) 96 assert_equal($collected_commands, []) 97 assert_equal(File.open_files.length, 0) 98 assert_equal(Pod::Executable.executed_commands.length, 0) 99 end 100 101 def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCodegenrepoExists_dontBuildCodegen() 102 103 # Arrange 104 File.mocked_existing_files([ 105 @base_path + "/build/" + @third_party_provider_header, 106 @base_path + "/build/tmpSchemaList.txt" 107 ]) 108 109 Dir.mocked_existing_dirs([ 110 @base_path + "/"+ @prefix + "/packages/react-native-codegen", 111 @base_path + "/"+ @prefix + "/packages/react-native-codegen/lib" 112 ]) 113 114 # Act 115 checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') 116 117 # Assert 118 assert_equal(Pathname.pwd_invocation_count, 1) 119 assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) 120 assert_equal(File.exist_invocation_params, [ 121 @base_path + "/build/" + @third_party_provider_header, 122 @base_path + "/build/" + @third_party_provider_implementation, 123 @base_path + "/build/tmpSchemaList.txt", 124 ]) 125 assert_equal(Dir.exist_invocation_params, [ 126 @base_path + "/"+ @prefix + "/packages/react-native-codegen", 127 @base_path + "/"+ @prefix + "/packages/react-native-codegen/lib", 128 ]) 129 assert_equal(Pod::UI.collected_messages, ["[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider"]) 130 assert_equal($collected_commands, []) 131 assert_equal(File.open_invocation_count, 1) 132 assert_equal(File.open_files_with_mode[@base_path + "/build/tmpSchemaList.txt"], 'w') 133 assert_equal(File.open_files[0].collected_write, ["[]"]) 134 assert_equal(File.open_files[0].fsync_invocation_count, 1) 135 assert_equal(Pod::Executable.executed_commands[0], { 136 "command" => "node", 137 "arguments" => [ 138 @base_path + "/" + @prefix + "/scripts/generate-provider-cli.js", 139 "--platform", 'ios', 140 "--schemaListPath", @base_path + "/build/tmpSchemaList.txt", 141 "--outputDir", @base_path + "/build" 142 ] 143 }) 144 assert_equal(File.delete_invocation_count, 1) 145 assert_equal(File.deleted_files, [@base_path + "/build/tmpSchemaList.txt"]) 146 end 147 148 def testCheckAndGenerateEmptyThirdPartyProvider_whenBothMissing_buildCodegen() 149 # Arrange 150 codegen_cli_path = @base_path + "/" + @prefix + "/../react-native-codegen" 151 Dir.mocked_existing_dirs([ 152 codegen_cli_path, 153 ]) 154 # Act 155 checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build') 156 157 # Assert 158 assert_equal(Pathname.pwd_invocation_count, 1) 159 assert_equal(Pod::Config.instance.installation_root.relative_path_from_invocation_count, 1) 160 assert_equal(File.exist_invocation_params, [ 161 @base_path + "/build/" + @third_party_provider_header, 162 @base_path + "/build/" + @tmp_schema_list_file 163 ]) 164 assert_equal(Dir.exist_invocation_params, [ 165 @base_path + "/" + @prefix + "/packages/react-native-codegen", 166 codegen_cli_path, 167 codegen_cli_path + "/lib", 168 ]) 169 assert_equal(Pod::UI.collected_messages, [ 170 "[Codegen] building #{codegen_cli_path}.", 171 "[Codegen] generating an empty RCTThirdPartyFabricComponentsProvider" 172 ]) 173 assert_equal($collected_commands, ["~/app/ios/../../../react-native-codegen/scripts/oss/build.sh"]) 174 assert_equal(File.open_files[0].collected_write, ["[]"]) 175 assert_equal(File.open_files[0].fsync_invocation_count, 1) 176 assert_equal(Pod::Executable.executed_commands[0], { 177 "command" => "node", 178 "arguments" => [ 179 @base_path + "/" + @prefix + "/scripts/generate-provider-cli.js", 180 "--platform", 'ios', 181 "--schemaListPath", @base_path + "/build/" + @tmp_schema_list_file, 182 "--outputDir", @base_path + "/build" 183 ] 184 }) 185 end 186 187 # ================= # 188 # Test - RunCodegen # 189 # ================= # 190 def testRunCodegen_whenNewArchEnabled_runsCodegen 191 # Arrange 192 app_path = "~/app" 193 config_file = "" 194 codegen_utils_mock = CodegenUtilsMock.new() 195 196 # Act 197 run_codegen!(app_path, config_file, :new_arch_enabled => true, :codegen_utils => codegen_utils_mock) 198 199 # Assert 200 assert_equal(codegen_utils_mock.use_react_native_codegen_discovery_params, [{ 201 :app_path=>"~/app", 202 :codegen_disabled=>false, 203 :codegen_output_dir=>"build/generated/ios", 204 :config_file_dir=>"", 205 :fabric_enabled=>false, 206 :folly_version=>"2021.07.22.00", 207 :react_native_path=>"../node_modules/react-native" 208 }]) 209 assert_equal(codegen_utils_mock.get_react_codegen_spec_params, []) 210 assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, []) 211 end 212 213 def testRunCodegen_whenNewArchDisabled_runsCodegen 214 # Arrange 215 app_path = "~/app" 216 config_file = "" 217 package_json_file = "~/app/package.json" 218 codegen_specs = { "name" => "ABI48_0_0React-Codegen" } 219 codegen_utils_mock = CodegenUtilsMock.new(:react_codegen_spec => codegen_specs) 220 221 # Act 222 run_codegen!( 223 app_path, 224 config_file, 225 :new_arch_enabled => false, 226 :fabric_enabled => true, 227 :package_json_file => package_json_file, 228 :codegen_utils => codegen_utils_mock) 229 230 # Assert 231 assert_equal(codegen_utils_mock.use_react_native_codegen_discovery_params, []) 232 assert_equal(codegen_utils_mock.get_react_codegen_spec_params, [{ 233 :fabric_enabled => true, 234 :folly_version=>"2021.07.22.00", 235 :package_json_file => "~/app/package.json", 236 :script_phases => nil 237 }]) 238 assert_equal(codegen_utils_mock.generate_react_codegen_spec_params, [{ 239 :codegen_output_dir=>"build/generated/ios", 240 :react_codegen_spec=>{"name"=>"ABI48_0_0React-Codegen"} 241 }]) 242 243 end 244end 245