Skip to content

Commit

Permalink
Use FileMock and DirMock instead of Monkey Patching (#35792)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #35792

This Diff fixes a problem we have when running Ruby tests.

The previous approach was monkey-patching the Ruby File and Dir classes to override some behaviours we needed during tests. However, these classes are also used by the test runners to properly read and run the tests, therefore when the tests were failing, the stream weren't closed properly and we received the wrong errors.

This problem was also preventing us from adopting other Ruby tools like SimpleCov to compute code coverage.

## Changelog:
[internal] - refactor Ruby tests not to monkey patch Dir and File

Reviewed By: dmytrorykun

Differential Revision: D42414717

fbshipit-source-id: 879b9928da1a083ebf9c81b1f510eaa039376042
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Jan 10, 2023
1 parent 8bef1b3 commit 88a1b8e
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 196 deletions.
60 changes: 29 additions & 31 deletions scripts/cocoapods/__tests__/codegen-test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class CodegenTests < Test::Unit::TestCase
:tmp_schema_list_file

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

@prefix = "../.."
Expand All @@ -38,8 +36,8 @@ def teardown
Pod::UI.reset()
Pod::Executable.reset()
Pathname.reset()
File.reset()
Dir.reset()
FileMock.reset()
DirMock.reset()
end

# ============================================== #
Expand All @@ -48,90 +46,90 @@ def teardown
def testCheckAndGenerateEmptyThirdPartyProvider_whenFileAlreadyExists_doNothing()

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

# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build', 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(File.exist_invocation_params, [
assert_equal(FileMock.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(DirMock.exist_invocation_params, [])
assert_equal(Pod::UI.collected_messages, [])
assert_equal($collected_commands, [])
assert_equal(File.open_files.length, 0)
assert_equal(FileMock.open_files.length, 0)
assert_equal(Pod::Executable.executed_commands.length, 0)
end

def testCheckAndGenerateEmptyThirdPartyProvider_whenHeaderMissingAndCodegenMissing_raiseError()

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

# Act
assert_raise {
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build', 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(File.exist_invocation_params, [
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/build/" + @third_party_provider_header
])
assert_equal(Dir.exist_invocation_params, [
assert_equal(DirMock.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(FileMock.open_files.length, 0)
assert_equal(Pod::Executable.executed_commands.length, 0)
end

def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCodegenrepoExists_dontBuildCodegen()

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

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

# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build', 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(File.exist_invocation_params, [
assert_equal(FileMock.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, [
assert_equal(DirMock.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(FileMock.open_invocation_count, 1)
assert_equal(FileMock.open_files_with_mode[@base_path + "/build/tmpSchemaList.txt"], 'w')
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" => [
Expand All @@ -141,27 +139,27 @@ def testCheckAndGenerateEmptyThirdPartyProvider_whenImplementationMissingAndCode
"--outputDir", @base_path + "/build"
]
})
assert_equal(File.delete_invocation_count, 1)
assert_equal(File.deleted_files, [@base_path + "/build/tmpSchemaList.txt"])
assert_equal(FileMock.delete_invocation_count, 1)
assert_equal(FileMock.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([
DirMock.mocked_existing_dirs([
codegen_cli_path,
])
# Act
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build')
checkAndGenerateEmptyThirdPartyProvider!(@prefix, false, 'build', 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(File.exist_invocation_params, [
assert_equal(FileMock.exist_invocation_params, [
@base_path + "/build/" + @third_party_provider_header,
@base_path + "/build/" + @tmp_schema_list_file
])
assert_equal(Dir.exist_invocation_params, [
assert_equal(DirMock.exist_invocation_params, [
@base_path + "/" + @prefix + "/packages/react-native-codegen",
codegen_cli_path,
codegen_cli_path + "/lib",
Expand All @@ -171,8 +169,8 @@ def testCheckAndGenerateEmptyThirdPartyProvider_whenBothMissing_buildCodegen()
"[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(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" => [
Expand Down
Loading

0 comments on commit 88a1b8e

Please sign in to comment.