Skip to content

Commit da405f2

Browse files
authored
Add new helper to more thoroughly test Fastlane action invocations (#330)
2 parents 9061436 + 8448e02 commit da405f2

9 files changed

+116
-42
lines changed

.rubocop_todo.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ RSpec/FilePath:
131131
- 'spec/android_localize_helper_spec.rb'
132132
- 'spec/android_merge_translators_strings_spec.rb'
133133
- 'spec/android_version_helper_spec.rb'
134+
- 'spec/an_localize_libs_action_spec.rb'
134135
- 'spec/an_metadata_update_helper_spec.rb'
135136
- 'spec/an_update_metadata_source_spec.rb'
136137
- 'spec/configuration_spec.rb'

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ _None_
2020

2121
* Ensure that the `gem push` step only runs on CI if lint, test and danger steps passed before it. [#325]
2222
* Rename internal `Ios::L10nHelper` to `Ios::L10nLinterHelper`. [#328]
23+
* Provide new `run_described_fastlane_action` to run Fastlane actions more thoroughly in unit tests [#330]
2324

2425
## 2.3.0
2526

spec/an_localize_libs_action_spec.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
require 'spec_helper'
2+
3+
describe Fastlane::Actions::AnLocalizeLibsAction do
4+
# This test is more of a way of ensuring `run_described_fastlane_action` handles array
5+
# of hashes properly than a comprehensive test for the
6+
# `an_localize_libs_action` action.
7+
#
8+
# Please consider expanding this test if you'll find yourself working on its
9+
# action.
10+
it 'merges the strings from the given array into the given main strings file' do
11+
in_tmp_dir do |tmp_dir|
12+
app_strings_path = File.join(tmp_dir, 'app.xml')
13+
File.write(app_strings_path, android_xml_with_content('<string name="a_string">test from app</string>'))
14+
15+
lib1_strings_path = File.join(tmp_dir, 'lib1.xml')
16+
File.write(lib1_strings_path, android_xml_with_content('<string name="a_lib1_string">test from lib 1</string>'))
17+
18+
lib2_strings_path = File.join(tmp_dir, 'lib2.xml')
19+
File.write(lib2_strings_path, android_xml_with_content('<string name="a_lib2_string">test from lib 2</string>'))
20+
21+
run_described_fastlane_action(
22+
app_strings_path: app_strings_path,
23+
libs_strings_path: [
24+
{ library: 'lib_1', strings_path: lib1_strings_path, exclusions: [] },
25+
{ library: 'lib_2', strings_path: lib2_strings_path, exclusions: [] },
26+
]
27+
)
28+
29+
# Notice the extra indentation in the library strings. The action doesn't
30+
# modify the app's strings content indentation, but it applies its own
31+
# standard to the values read from the given library strings
32+
expected = <<~XML
33+
<string name="a_string">test from app</string>
34+
<string name="a_lib1_string">test from lib 1</string>
35+
<string name="a_lib2_string">test from lib 2</string>
36+
XML
37+
expect(File.read(app_strings_path)).to eq(android_xml_with_content(expected))
38+
end
39+
end
40+
end
41+
42+
def android_xml_with_content(content)
43+
# I couldn't find a way to interpolate a multiline string preserving its
44+
# indentation in the heredoc below, so I hacked the following transformation
45+
# of the input that adds the desired indentation to all lines.
46+
indented_content = content.chomp.lines.map { |l| " #{l}" }.join
47+
48+
return <<~XML
49+
<?xml version="1.0" encoding="UTF-8"?>
50+
<resources xmlns:tools="http://schemas.android.com/tools">
51+
#{indented_content}
52+
</resources>
53+
XML
54+
end

spec/android_merge_translators_strings_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
def amts_run_test(script)
3636
test_script = @amtsTestUtils.get_test_from_file(script)
3737
@amtsTestUtils.create_test_data(test_script)
38-
Fastlane::Actions::AndroidMergeTranslatorsStringsAction.run(strings_folder: @amtsTestUtils.test_folder_path)
38+
run_described_fastlane_action(strings_folder: @amtsTestUtils.test_folder_path)
3939
expect(@amtsTestUtils.read_result_data(test_script)).to eq(test_script['result']['content'])
4040
end
4141

spec/ios_lint_localizations_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
expect(FileUtils).to receive(:cp_r)
2424
expect_shell_command("#{install_dir}/bin/swiftgen", 'config', 'run', '--config', anything)
2525

26-
Fastlane::Actions::IosLintLocalizationsAction.run(
26+
run_described_fastlane_action(
2727
install_path: install_dir,
2828
input_dir: empty_dataset,
2929
base_lang: 'en'
@@ -43,7 +43,7 @@
4343
# Second run: ensure we only run SwiftGen directly, without a call to curl nor unzip beforehand
4444
expect_shell_command("#{install_dir}/bin/swiftgen", 'config', 'run', '--config', anything)
4545

46-
Fastlane::Actions::IosLintLocalizationsAction.run(
46+
run_described_fastlane_action(
4747
install_path: install_dir,
4848
input_dir: empty_dataset,
4949
base_lang: 'en'
@@ -103,7 +103,7 @@ def run_l10n_linter_test(data_file)
103103
# remove this after the test ends, so that further executions of the test run faster.
104104
# Only the first execution of the tests might take longer if it needs to install SwiftGen first to be able to run the tests.
105105
install_dir = "vendor/swiftgen/#{Fastlane::Helper::Ios::L10nLinterHelper::SWIFTGEN_VERSION}"
106-
result = Fastlane::Actions::IosLintLocalizationsAction.run(
106+
result = run_described_fastlane_action(
107107
install_path: install_dir,
108108
input_dir: @test_data_dir,
109109
base_lang: 'en'

spec/ios_merge_strings_files_spec.rb

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
1-
describe Fastlane do
2-
describe Fastlane::FastFile do
3-
let(:test_data_dir) { File.join(File.dirname(__FILE__), 'test-data', 'translations', 'ios_l10n_helper') }
1+
describe Fastlane::Actions::IosMergeStringsFilesAction do
2+
let(:test_data_dir) { File.join(File.dirname(__FILE__), 'test-data', 'translations', 'ios_l10n_helper') }
43

5-
def fixture(name)
6-
File.join(test_data_dir, name)
7-
end
8-
9-
describe '#ios_merge_strings_files' do
10-
it 'calls the action with the proper parameters and warn and return duplicate keys' do
11-
# Arrange
12-
messages = []
13-
allow(FastlaneCore::UI).to receive(:important) do |message|
14-
messages.append(message)
15-
end
16-
inputs = ['Localizable-utf16.strings', 'non-latin-utf16.strings']
4+
def fixture(name)
5+
File.join(test_data_dir, name)
6+
end
177

18-
Dir.mktmpdir('a8c-release-toolkit-tests-') do |tmpdir|
19-
inputs.each { |f| FileUtils.cp(fixture(f), tmpdir) }
8+
describe '#ios_merge_strings_files' do
9+
it 'calls the action with the proper parameters and warn and return duplicate keys' do
10+
# Arrange
11+
messages = []
12+
allow(FastlaneCore::UI).to receive(:important) do |message|
13+
messages.append(message)
14+
end
15+
inputs = ['Localizable-utf16.strings', 'non-latin-utf16.strings']
2016

21-
# Act
22-
result = Dir.chdir(tmpdir) do
23-
described_class.new.parse("lane :test do
24-
ios_merge_strings_files(
25-
paths: ['#{inputs[0]}', '#{inputs[1]}'],
26-
destination: 'output.strings'
27-
)
28-
end").runner.execute(:test)
29-
end
17+
Dir.mktmpdir('a8c-release-toolkit-tests-') do |tmpdir|
18+
inputs.each { |f| FileUtils.cp(fixture(f), tmpdir) }
3019

31-
# Assert
32-
expect(File).to exist(File.join(tmpdir, 'output.strings'))
33-
expect(result).to eq(%w[key1 key2])
34-
expect(messages).to eq([
35-
'Duplicate key found while merging the `.strings` files: `key1`',
36-
'Duplicate key found while merging the `.strings` files: `key2`',
37-
])
20+
# Act
21+
result = Dir.chdir(tmpdir) do
22+
run_described_fastlane_action(
23+
paths: [inputs[0], inputs[1]],
24+
destination: 'output.strings'
25+
)
3826
end
27+
28+
# Assert
29+
expect(File).to exist(File.join(tmpdir, 'output.strings'))
30+
expect(result).to eq(%w[key1 key2])
31+
expect(messages).to eq(
32+
[
33+
'Duplicate key found while merging the `.strings` files: `key1`',
34+
'Duplicate key found while merging the `.strings` files: `key2`',
35+
]
36+
)
3937
end
4038
end
4139
end

spec/ios_merge_translators_strings_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
def imts_run_test(script)
3636
test_script = @imtsTestUtils.get_test_from_file(script)
3737
@imtsTestUtils.create_test_data(test_script)
38-
Fastlane::Actions::IosMergeTranslatorsStringsAction.run(strings_folder: @imtsTestUtils.test_folder_path)
38+
run_described_fastlane_action(strings_folder: @imtsTestUtils.test_folder_path)
3939
expect(@imtsTestUtils.read_result_data(test_script)).to eq(test_script['result']['content'])
4040
end
4141

spec/shared_examples_for_update_metadata_source_action.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
file_2_path = File.join(dir, '2.txt')
2020
File.write(file_2_path, 'value 2')
2121

22-
described_class.run(
22+
run_described_fastlane_action(
2323
po_file_path: output_path,
24+
release_version: '1.0',
2425
source_files: {
2526
key1: file_1_path,
2627
key2: file_2_path
@@ -56,7 +57,7 @@
5657
whats_new_path = File.join(dir, 'whats_new.txt')
5758
File.write(whats_new_path, "- something new\n- something else new")
5859

59-
described_class.run(
60+
run_described_fastlane_action(
6061
po_file_path: output_path,
6162
release_version: '1.23',
6263
source_files: {
@@ -94,8 +95,9 @@
9495
file_2_path = File.join(dir, '2.txt')
9596
File.write(file_2_path, 'value 2')
9697

97-
described_class.run(
98+
run_described_fastlane_action(
9899
po_file_path: output_path,
100+
release_version: '1.0',
99101
source_files: {
100102
key1: file_1_path,
101103
key2: file_2_path
@@ -135,7 +137,7 @@
135137
release_notes_path = File.join(dir, 'release_notes.txt')
136138
File.write(release_notes_path, "- release notes\n- more release notes")
137139

138-
described_class.run(
140+
run_described_fastlane_action(
139141
po_file_path: output_path,
140142
release_version: '1.23',
141143
source_files: {

spec/spec_helper.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ def expect_shell_command(*command, exitstatus: 0, output: '')
6767
expect(Open3).to receive(:popen2e).with(*command).and_yield(mock_input, mock_output, mock_thread)
6868
end
6969

70+
# If the `described_class` of a spec is a `Fastlane::Action` subclass, it runs
71+
# it with the given parameters.
72+
#
73+
def run_described_fastlane_action(parameters)
74+
raise "Only call `#{__callee__}` from a spec describing a `Fastlane::Action` subclass." unless Fastlane::Actions.is_class_action?(described_class)
75+
76+
# Avoid logging messages about deprecated actions while running tests on them
77+
allow(Fastlane::Actions).to receive(:is_deprecated?).and_return(false)
78+
lane = <<~LANE
79+
lane :test do
80+
#{described_class.action_name}(
81+
#{parameters.inspect}
82+
)
83+
end
84+
LANE
85+
Fastlane::FastFile.new.parse(lane).runner.execute(:test)
86+
end
87+
7088
# Executes the given block within an ad hoc temporary directory.
7189
def in_tmp_dir
7290
Dir.mktmpdir('a8c-release-toolkit-tests-') do |tmpdir|

0 commit comments

Comments
 (0)