diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 2dea29051..0c088ef80 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -131,6 +131,7 @@ RSpec/FilePath:
- 'spec/android_localize_helper_spec.rb'
- 'spec/android_merge_translators_strings_spec.rb'
- 'spec/android_version_helper_spec.rb'
+ - 'spec/an_localize_libs_action_spec.rb'
- 'spec/an_metadata_update_helper_spec.rb'
- 'spec/an_update_metadata_source_spec.rb'
- 'spec/configuration_spec.rb'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86f7618b9..9d8e9685c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ _None_
* Ensure that the `gem push` step only runs on CI if lint, test and danger steps passed before it. [#325]
* Rename internal `Ios::L10nHelper` to `Ios::L10nLinterHelper`. [#328]
+* Provide new `run_described_fastlane_action` to run Fastlane actions more thoroughly in unit tests [#330]
## 2.3.0
diff --git a/spec/an_localize_libs_action_spec.rb b/spec/an_localize_libs_action_spec.rb
new file mode 100644
index 000000000..86455e3a7
--- /dev/null
+++ b/spec/an_localize_libs_action_spec.rb
@@ -0,0 +1,54 @@
+require 'spec_helper'
+
+describe Fastlane::Actions::AnLocalizeLibsAction do
+ # This test is more of a way of ensuring `run_described_fastlane_action` handles array
+ # of hashes properly than a comprehensive test for the
+ # `an_localize_libs_action` action.
+ #
+ # Please consider expanding this test if you'll find yourself working on its
+ # action.
+ it 'merges the strings from the given array into the given main strings file' do
+ in_tmp_dir do |tmp_dir|
+ app_strings_path = File.join(tmp_dir, 'app.xml')
+ File.write(app_strings_path, android_xml_with_content('test from app'))
+
+ lib1_strings_path = File.join(tmp_dir, 'lib1.xml')
+ File.write(lib1_strings_path, android_xml_with_content('test from lib 1'))
+
+ lib2_strings_path = File.join(tmp_dir, 'lib2.xml')
+ File.write(lib2_strings_path, android_xml_with_content('test from lib 2'))
+
+ run_described_fastlane_action(
+ app_strings_path: app_strings_path,
+ libs_strings_path: [
+ { library: 'lib_1', strings_path: lib1_strings_path, exclusions: [] },
+ { library: 'lib_2', strings_path: lib2_strings_path, exclusions: [] },
+ ]
+ )
+
+ # Notice the extra indentation in the library strings. The action doesn't
+ # modify the app's strings content indentation, but it applies its own
+ # standard to the values read from the given library strings
+ expected = <<~XML
+ test from app
+ test from lib 1
+ test from lib 2
+ XML
+ expect(File.read(app_strings_path)).to eq(android_xml_with_content(expected))
+ end
+ end
+end
+
+def android_xml_with_content(content)
+ # I couldn't find a way to interpolate a multiline string preserving its
+ # indentation in the heredoc below, so I hacked the following transformation
+ # of the input that adds the desired indentation to all lines.
+ indented_content = content.chomp.lines.map { |l| " #{l}" }.join
+
+ return <<~XML
+
+
+ #{indented_content}
+
+ XML
+end
diff --git a/spec/android_merge_translators_strings_spec.rb b/spec/android_merge_translators_strings_spec.rb
index f11c7e8b4..e7695b7ae 100644
--- a/spec/android_merge_translators_strings_spec.rb
+++ b/spec/android_merge_translators_strings_spec.rb
@@ -35,7 +35,7 @@
def amts_run_test(script)
test_script = @amtsTestUtils.get_test_from_file(script)
@amtsTestUtils.create_test_data(test_script)
- Fastlane::Actions::AndroidMergeTranslatorsStringsAction.run(strings_folder: @amtsTestUtils.test_folder_path)
+ run_described_fastlane_action(strings_folder: @amtsTestUtils.test_folder_path)
expect(@amtsTestUtils.read_result_data(test_script)).to eq(test_script['result']['content'])
end
diff --git a/spec/ios_lint_localizations_spec.rb b/spec/ios_lint_localizations_spec.rb
index 4e6ac3888..036acff29 100644
--- a/spec/ios_lint_localizations_spec.rb
+++ b/spec/ios_lint_localizations_spec.rb
@@ -23,7 +23,7 @@
expect(FileUtils).to receive(:cp_r)
expect_shell_command("#{install_dir}/bin/swiftgen", 'config', 'run', '--config', anything)
- Fastlane::Actions::IosLintLocalizationsAction.run(
+ run_described_fastlane_action(
install_path: install_dir,
input_dir: empty_dataset,
base_lang: 'en'
@@ -43,7 +43,7 @@
# Second run: ensure we only run SwiftGen directly, without a call to curl nor unzip beforehand
expect_shell_command("#{install_dir}/bin/swiftgen", 'config', 'run', '--config', anything)
- Fastlane::Actions::IosLintLocalizationsAction.run(
+ run_described_fastlane_action(
install_path: install_dir,
input_dir: empty_dataset,
base_lang: 'en'
@@ -103,7 +103,7 @@ def run_l10n_linter_test(data_file)
# remove this after the test ends, so that further executions of the test run faster.
# Only the first execution of the tests might take longer if it needs to install SwiftGen first to be able to run the tests.
install_dir = "vendor/swiftgen/#{Fastlane::Helper::Ios::L10nLinterHelper::SWIFTGEN_VERSION}"
- result = Fastlane::Actions::IosLintLocalizationsAction.run(
+ result = run_described_fastlane_action(
install_path: install_dir,
input_dir: @test_data_dir,
base_lang: 'en'
diff --git a/spec/ios_merge_strings_files_spec.rb b/spec/ios_merge_strings_files_spec.rb
index cba549a18..22bd4cc2d 100644
--- a/spec/ios_merge_strings_files_spec.rb
+++ b/spec/ios_merge_strings_files_spec.rb
@@ -1,41 +1,39 @@
-describe Fastlane do
- describe Fastlane::FastFile do
- let(:test_data_dir) { File.join(File.dirname(__FILE__), 'test-data', 'translations', 'ios_l10n_helper') }
+describe Fastlane::Actions::IosMergeStringsFilesAction do
+ let(:test_data_dir) { File.join(File.dirname(__FILE__), 'test-data', 'translations', 'ios_l10n_helper') }
- def fixture(name)
- File.join(test_data_dir, name)
- end
-
- describe '#ios_merge_strings_files' do
- it 'calls the action with the proper parameters and warn and return duplicate keys' do
- # Arrange
- messages = []
- allow(FastlaneCore::UI).to receive(:important) do |message|
- messages.append(message)
- end
- inputs = ['Localizable-utf16.strings', 'non-latin-utf16.strings']
+ def fixture(name)
+ File.join(test_data_dir, name)
+ end
- Dir.mktmpdir('a8c-release-toolkit-tests-') do |tmpdir|
- inputs.each { |f| FileUtils.cp(fixture(f), tmpdir) }
+ describe '#ios_merge_strings_files' do
+ it 'calls the action with the proper parameters and warn and return duplicate keys' do
+ # Arrange
+ messages = []
+ allow(FastlaneCore::UI).to receive(:important) do |message|
+ messages.append(message)
+ end
+ inputs = ['Localizable-utf16.strings', 'non-latin-utf16.strings']
- # Act
- result = Dir.chdir(tmpdir) do
- described_class.new.parse("lane :test do
- ios_merge_strings_files(
- paths: ['#{inputs[0]}', '#{inputs[1]}'],
- destination: 'output.strings'
- )
- end").runner.execute(:test)
- end
+ Dir.mktmpdir('a8c-release-toolkit-tests-') do |tmpdir|
+ inputs.each { |f| FileUtils.cp(fixture(f), tmpdir) }
- # Assert
- expect(File).to exist(File.join(tmpdir, 'output.strings'))
- expect(result).to eq(%w[key1 key2])
- expect(messages).to eq([
- 'Duplicate key found while merging the `.strings` files: `key1`',
- 'Duplicate key found while merging the `.strings` files: `key2`',
- ])
+ # Act
+ result = Dir.chdir(tmpdir) do
+ run_described_fastlane_action(
+ paths: [inputs[0], inputs[1]],
+ destination: 'output.strings'
+ )
end
+
+ # Assert
+ expect(File).to exist(File.join(tmpdir, 'output.strings'))
+ expect(result).to eq(%w[key1 key2])
+ expect(messages).to eq(
+ [
+ 'Duplicate key found while merging the `.strings` files: `key1`',
+ 'Duplicate key found while merging the `.strings` files: `key2`',
+ ]
+ )
end
end
end
diff --git a/spec/ios_merge_translators_strings_spec.rb b/spec/ios_merge_translators_strings_spec.rb
index f20eebfef..4ae829f8f 100644
--- a/spec/ios_merge_translators_strings_spec.rb
+++ b/spec/ios_merge_translators_strings_spec.rb
@@ -35,7 +35,7 @@
def imts_run_test(script)
test_script = @imtsTestUtils.get_test_from_file(script)
@imtsTestUtils.create_test_data(test_script)
- Fastlane::Actions::IosMergeTranslatorsStringsAction.run(strings_folder: @imtsTestUtils.test_folder_path)
+ run_described_fastlane_action(strings_folder: @imtsTestUtils.test_folder_path)
expect(@imtsTestUtils.read_result_data(test_script)).to eq(test_script['result']['content'])
end
diff --git a/spec/shared_examples_for_update_metadata_source_action.rb b/spec/shared_examples_for_update_metadata_source_action.rb
index 2c82949df..d096096e2 100644
--- a/spec/shared_examples_for_update_metadata_source_action.rb
+++ b/spec/shared_examples_for_update_metadata_source_action.rb
@@ -19,8 +19,9 @@
file_2_path = File.join(dir, '2.txt')
File.write(file_2_path, 'value 2')
- described_class.run(
+ run_described_fastlane_action(
po_file_path: output_path,
+ release_version: '1.0',
source_files: {
key1: file_1_path,
key2: file_2_path
@@ -56,7 +57,7 @@
whats_new_path = File.join(dir, 'whats_new.txt')
File.write(whats_new_path, "- something new\n- something else new")
- described_class.run(
+ run_described_fastlane_action(
po_file_path: output_path,
release_version: '1.23',
source_files: {
@@ -94,8 +95,9 @@
file_2_path = File.join(dir, '2.txt')
File.write(file_2_path, 'value 2')
- described_class.run(
+ run_described_fastlane_action(
po_file_path: output_path,
+ release_version: '1.0',
source_files: {
key1: file_1_path,
key2: file_2_path
@@ -135,7 +137,7 @@
release_notes_path = File.join(dir, 'release_notes.txt')
File.write(release_notes_path, "- release notes\n- more release notes")
- described_class.run(
+ run_described_fastlane_action(
po_file_path: output_path,
release_version: '1.23',
source_files: {
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9fc311a64..8bc4ad62d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -67,6 +67,24 @@ def expect_shell_command(*command, exitstatus: 0, output: '')
expect(Open3).to receive(:popen2e).with(*command).and_yield(mock_input, mock_output, mock_thread)
end
+# If the `described_class` of a spec is a `Fastlane::Action` subclass, it runs
+# it with the given parameters.
+#
+def run_described_fastlane_action(parameters)
+ raise "Only call `#{__callee__}` from a spec describing a `Fastlane::Action` subclass." unless Fastlane::Actions.is_class_action?(described_class)
+
+ # Avoid logging messages about deprecated actions while running tests on them
+ allow(Fastlane::Actions).to receive(:is_deprecated?).and_return(false)
+ lane = <<~LANE
+ lane :test do
+ #{described_class.action_name}(
+ #{parameters.inspect}
+ )
+ end
+ LANE
+ Fastlane::FastFile.new.parse(lane).runner.execute(:test)
+end
+
# Executes the given block within an ad hoc temporary directory.
def in_tmp_dir
Dir.mktmpdir('a8c-release-toolkit-tests-') do |tmpdir|