lokalise_rails 2.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/Gemfile +12 -1
  4. data/README.md +74 -57
  5. data/lib/generators/lokalise_rails/install_generator.rb +2 -0
  6. data/lib/generators/templates/lokalise_rails_config.rb +2 -4
  7. data/lib/lokalise_rails/global_config.rb +12 -0
  8. data/lib/lokalise_rails/railtie.rb +1 -0
  9. data/lib/lokalise_rails/utils.rb +23 -0
  10. data/lib/lokalise_rails/version.rb +3 -1
  11. data/lib/lokalise_rails.rb +8 -88
  12. data/lib/tasks/lokalise_rails_tasks.rake +6 -3
  13. data/lokalise_rails.gemspec +7 -18
  14. data/spec/dummy/config/lokalise_rails.rb +3 -3
  15. data/spec/lib/generators/lokalise_rails/install_generator_spec.rb +2 -2
  16. data/spec/lib/{lokalise_rails_spec.rb → lokalise_rails/global_config_spec.rb} +17 -5
  17. data/spec/lib/lokalise_rails/version_spec.rb +7 -0
  18. data/spec/lib/tasks/export_task_spec.rb +25 -18
  19. data/spec/lib/tasks/import_task_spec.rb +36 -99
  20. data/spec/lib/utils_spec.rb +16 -0
  21. data/spec/spec_helper.rb +0 -2
  22. data/spec/support/file_manager.rb +8 -11
  23. data/spec/support/spec_addons.rb +8 -3
  24. metadata +21 -178
  25. data/lib/lokalise_rails/error.rb +0 -10
  26. data/lib/lokalise_rails/task_definition/base.rb +0 -80
  27. data/lib/lokalise_rails/task_definition/exporter.rb +0 -79
  28. data/lib/lokalise_rails/task_definition/importer.rb +0 -109
  29. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -9
  30. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
  31. data/spec/dummy/config/initializers/content_security_policy.rb +0 -29
  32. data/spec/dummy/config/initializers/inflections.rb +0 -17
  33. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  34. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  35. data/spec/lib/lokalise_rails/task_definition/base_spec.rb +0 -81
  36. data/spec/lib/lokalise_rails/task_definition/exporter_spec.rb +0 -200
  37. data/spec/lib/lokalise_rails/task_definition/importer_spec.rb +0 -72
  38. data/spec/support/rake_utils.rb +0 -15
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ruby-lokalise-api'
4
- require 'pathname'
5
-
6
- module LokaliseRails
7
- module TaskDefinition
8
- class Base
9
- class << self
10
- attr_writer :api_client
11
-
12
- # Creates a Lokalise API client
13
- #
14
- # @return [Lokalise::Client]
15
- def api_client
16
- @api_client ||= ::Lokalise.client LokaliseRails.api_token, {enable_compression: true}.merge(LokaliseRails.timeouts)
17
- end
18
-
19
- # Resets API client
20
- def reset_api_client!
21
- Lokalise.reset_client!
22
- @api_client = nil
23
- end
24
-
25
- # Checks task options
26
- #
27
- # @return Array
28
- def check_options_errors!
29
- errors = []
30
- errors << 'Project ID is not set!' if LokaliseRails.project_id.nil? || LokaliseRails.project_id.empty?
31
- errors << 'Lokalise API token is not set!' if LokaliseRails.api_token.nil? || LokaliseRails.api_token.empty?
32
-
33
- raise(LokaliseRails::Error, errors.join(' ')) if errors.any?
34
- end
35
-
36
- private
37
-
38
- # Checks whether the provided file has a proper extension as dictated by the `file_ext_regexp` option
39
- #
40
- # @return Boolean
41
- # @param raw_path [String, Pathname]
42
- def proper_ext?(raw_path)
43
- path = raw_path.is_a?(Pathname) ? raw_path : Pathname.new(raw_path)
44
- LokaliseRails.file_ext_regexp.match? path.extname
45
- end
46
-
47
- # Returns directory and filename for the given entry
48
- #
49
- # @return Array
50
- # @param entry [String]
51
- def subdir_and_filename_for(entry)
52
- Pathname.new(entry).split
53
- end
54
-
55
- # Returns Lokalise project ID and branch, semicolumn separated
56
- #
57
- # @return [String]
58
- def project_id_with_branch
59
- "#{LokaliseRails.project_id}:#{LokaliseRails.branch}"
60
- end
61
-
62
- # Sends request with exponential backoff mechanism
63
- def with_exp_backoff(max_retries)
64
- return unless block_given?
65
-
66
- retries = 0
67
- begin
68
- yield
69
- rescue Lokalise::Error::TooManyRequests => e
70
- raise(e.class, "Gave up after #{retries} retries") if retries >= max_retries
71
-
72
- sleep 2**retries
73
- retries += 1
74
- retry
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- module LokaliseRails
6
- module TaskDefinition
7
- class Exporter < Base
8
- class << self
9
- # Performs translation file export from Rails to Lokalise and returns an array of queued processes
10
- #
11
- # @return [Array]
12
- def export!
13
- check_options_errors!
14
-
15
- queued_processes = []
16
- each_file do |full_path, relative_path|
17
- queued_processes << do_upload(full_path, relative_path)
18
- rescue StandardError => e
19
- raise e.class, "Error while trying to upload #{full_path}: #{e.message}"
20
- end
21
-
22
- $stdout.print 'Task complete!'
23
-
24
- queued_processes
25
- end
26
-
27
- # Performs the actual file uploading to Lokalise. If the API rate limit is exceeed,
28
- # applies exponential backoff
29
- def do_upload(f_path, r_path)
30
- with_exp_backoff(LokaliseRails.max_retries_export) do
31
- api_client.upload_file project_id_with_branch, opts(f_path, r_path)
32
- end
33
- end
34
-
35
- # Processes each translation file in the specified directory
36
- def each_file
37
- return unless block_given?
38
-
39
- loc_path = LokaliseRails.locales_path
40
- Dir["#{loc_path}/**/*"].sort.each do |f|
41
- full_path = Pathname.new f
42
-
43
- next unless file_matches_criteria? full_path
44
-
45
- relative_path = full_path.relative_path_from Pathname.new(loc_path)
46
-
47
- yield full_path, relative_path
48
- end
49
- end
50
-
51
- # Generates export options
52
- #
53
- # @return [Hash]
54
- # @param full_p [Pathname]
55
- # @param relative_p [Pathname]
56
- def opts(full_p, relative_p)
57
- content = File.read full_p
58
-
59
- initial_opts = {
60
- data: Base64.strict_encode64(content.strip),
61
- filename: relative_p,
62
- lang_iso: LokaliseRails.lang_iso_inferer.call(content)
63
- }
64
-
65
- initial_opts.merge LokaliseRails.export_opts
66
- end
67
-
68
- # Checks whether the specified file has to be processed or not
69
- #
70
- # @return [Boolean]
71
- # @param full_path [Pathname]
72
- def file_matches_criteria?(full_path)
73
- full_path.file? && proper_ext?(full_path) &&
74
- !LokaliseRails.skip_file_export.call(full_path)
75
- end
76
- end
77
- end
78
- end
79
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'zip'
4
- require 'yaml'
5
- require 'open-uri'
6
- require 'fileutils'
7
-
8
- module LokaliseRails
9
- module TaskDefinition
10
- class Importer < Base
11
- class << self
12
- # Performs translation files import from Lokalise to Rails app
13
- #
14
- # @return [Boolean]
15
- def import!
16
- check_options_errors!
17
-
18
- unless proceed_when_safe_mode?
19
- $stdout.print 'Task cancelled!'
20
- return false
21
- end
22
-
23
- open_and_process_zip download_files['bundle_url']
24
-
25
- $stdout.print 'Task complete!'
26
- true
27
- end
28
-
29
- # Downloads files from Lokalise using the specified options.
30
- # Utilizes exponential backoff if "too many requests" error is received
31
- #
32
- # @return [Hash]
33
- def download_files
34
- with_exp_backoff(LokaliseRails.max_retries_import) do
35
- api_client.download_files project_id_with_branch, LokaliseRails.import_opts
36
- end
37
- rescue StandardError => e
38
- raise e.class, "There was an error when trying to download files: #{e.message}"
39
- end
40
-
41
- # Opens ZIP archive (local or remote) with translations and processes its entries
42
- #
43
- # @param path [String]
44
- def open_and_process_zip(path)
45
- Zip::File.open_buffer(open_file_or_remote(path)) do |zip|
46
- fetch_zip_entries(zip) { |entry| process!(entry) }
47
- end
48
- rescue StandardError => e
49
- raise e.class, "There was an error when trying to process the downloaded files: #{e.message}"
50
- end
51
-
52
- # Iterates over ZIP entries. Each entry may be a file or folder.
53
- def fetch_zip_entries(zip)
54
- return unless block_given?
55
-
56
- zip.each do |entry|
57
- next unless proper_ext? entry.name
58
-
59
- yield entry
60
- end
61
- end
62
-
63
- # Processes ZIP entry by reading its contents and creating the corresponding translation file
64
- def process!(zip_entry)
65
- data = data_from zip_entry
66
- subdir, filename = subdir_and_filename_for zip_entry.name
67
- full_path = "#{LokaliseRails.locales_path}/#{subdir}"
68
- FileUtils.mkdir_p full_path
69
-
70
- File.open(File.join(full_path, filename), 'w+:UTF-8') do |f|
71
- f.write LokaliseRails.translations_converter.call(data)
72
- end
73
- rescue StandardError => e
74
- raise e.class, "Error when trying to process #{zip_entry&.name}: #{e.message}"
75
- end
76
-
77
- # Checks whether the user wishes to proceed when safe mode is enabled and the target directory is not empty
78
- #
79
- # @return [Boolean]
80
- def proceed_when_safe_mode?
81
- return true unless LokaliseRails.import_safe_mode && !Dir.empty?(LokaliseRails.locales_path.to_s)
82
-
83
- $stdout.puts "The target directory #{LokaliseRails.locales_path} is not empty!"
84
- $stdout.print 'Enter Y to continue: '
85
- answer = $stdin.gets
86
- answer.to_s.strip == 'Y'
87
- end
88
-
89
- # Opens a local file or a remote URL using the provided patf
90
- #
91
- # @return [String]
92
- def open_file_or_remote(path)
93
- parsed_path = URI.parse(path)
94
- if parsed_path&.scheme&.include?('http')
95
- parsed_path.open
96
- else
97
- File.open path
98
- end
99
- end
100
-
101
- private
102
-
103
- def data_from(zip_entry)
104
- LokaliseRails.translations_loader.call zip_entry.get_input_stream.read
105
- end
106
- end
107
- end
108
- end
109
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
- # Be sure to restart your server when you modify this file.
3
-
4
- # ActiveSupport::Reloader.to_prepare do
5
- # ApplicationController.renderer.defaults.merge!(
6
- # http_host: 'example.org',
7
- # https: false
8
- # )
9
- # end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
- # Be sure to restart your server when you modify this file.
3
-
4
- # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
5
- # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
6
-
7
- # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
8
- # Rails.backtrace_cleaner.remove_silencers!
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
- # Be sure to restart your server when you modify this file.
3
-
4
- # Define an application-wide content security policy
5
- # For further information see the following documentation
6
- # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
7
-
8
- # Rails.application.config.content_security_policy do |policy|
9
- # policy.default_src :self, :https
10
- # policy.font_src :self, :https, :data
11
- # policy.img_src :self, :https, :data
12
- # policy.object_src :none
13
- # policy.script_src :self, :https
14
- # policy.style_src :self, :https
15
-
16
- # # Specify URI for violation reports
17
- # # policy.report_uri "/csp-violation-report-endpoint"
18
- # end
19
-
20
- # If you are using UJS then enable automatic nonce generation
21
- # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
22
-
23
- # Set the nonce only to specific directives
24
- # Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
25
-
26
- # Report CSP violations to a specified URI
27
- # For further information see the following documentation:
28
- # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
29
- # Rails.application.config.content_security_policy_report_only = true
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
- # Be sure to restart your server when you modify this file.
3
-
4
- # Add new inflection rules using the following format. Inflections
5
- # are locale specific, and you may define rules for as many different
6
- # locales as you wish. All of these examples are active by default:
7
- # ActiveSupport::Inflector.inflections(:en) do |inflect|
8
- # inflect.plural /^(ox)$/i, '\1en'
9
- # inflect.singular /^(ox)en/i, '\1'
10
- # inflect.irregular 'person', 'people'
11
- # inflect.uncountable %w( fish sheep )
12
- # end
13
-
14
- # These inflection rules are supported but not enabled by default:
15
- # ActiveSupport::Inflector.inflections(:en) do |inflect|
16
- # inflect.acronym 'RESTful'
17
- # end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
- # Be sure to restart your server when you modify this file.
3
-
4
- # Add new mime types for use in respond_to blocks:
5
- # Mime::Type.register "text/richtext", :rtf
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Be sure to restart your server when you modify this file.
4
-
5
- # This file contains settings for ActionController::ParamsWrapper which
6
- # is enabled by default.
7
-
8
- # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
9
- ActiveSupport.on_load(:action_controller) do
10
- wrap_parameters format: [:json]
11
- end
12
-
13
- # To enable root element in JSON for ActiveRecord objects.
14
- # ActiveSupport.on_load(:active_record) do
15
- # self.include_root_in_json = true
16
- # end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe LokaliseRails::TaskDefinition::Base do
4
- specify '.reset_client!' do
5
- expect(described_class.api_client).to be_an_instance_of(Lokalise::Client)
6
- described_class.reset_api_client!
7
- current_client = described_class.instance_variable_get '@api_client'
8
- expect(current_client).to be_nil
9
- end
10
-
11
- specify '.project_id_with_branch!' do
12
- result = described_class.send :project_id_with_branch
13
- expect(result).to be_an_instance_of(String)
14
- expect(result).to include(':master')
15
- end
16
-
17
- describe '.subdir_and_filename_for' do
18
- it 'works properly for longer paths' do
19
- path = 'my_path/is/here/file.yml'
20
- result = described_class.send(:subdir_and_filename_for, path)
21
- expect(result.length).to eq(2)
22
- expect(result[0]).to be_an_instance_of(Pathname)
23
- expect(result[0].to_s).to eq('my_path/is/here')
24
- expect(result[1].to_s).to eq('file.yml')
25
- end
26
-
27
- it 'works properly for shorter paths' do
28
- path = 'file.yml'
29
- result = described_class.send(:subdir_and_filename_for, path)
30
- expect(result.length).to eq(2)
31
- expect(result[1]).to be_an_instance_of(Pathname)
32
- expect(result[0].to_s).to eq('.')
33
- expect(result[1].to_s).to eq('file.yml')
34
- end
35
- end
36
-
37
- describe '.check_options_errors!' do
38
- it 'raises an error when the API key is not set' do
39
- allow(LokaliseRails).to receive(:api_token).and_return(nil)
40
-
41
- expect(-> { described_class.check_options_errors! }).to raise_error(LokaliseRails::Error, /API token is not set/i)
42
-
43
- expect(LokaliseRails).to have_received(:api_token)
44
- end
45
-
46
- it 'returns an error when the project_id is not set' do
47
- allow_project_id nil do
48
- expect(-> { described_class.check_options_errors! }).to raise_error(LokaliseRails::Error, /ID is not set/i)
49
- end
50
- end
51
- end
52
-
53
- describe '.proper_ext?' do
54
- it 'works properly with path represented as a string' do
55
- path = 'my_path/here/file.yml'
56
- expect(described_class.send(:proper_ext?, path)).to be true
57
- end
58
-
59
- it 'works properly with path represented as a pathname' do
60
- path = Pathname.new 'my_path/here/file.json'
61
- expect(described_class.send(:proper_ext?, path)).to be false
62
- end
63
- end
64
-
65
- describe '.api_client' do
66
- before(:all) { described_class.reset_api_client! }
67
-
68
- after(:all) { described_class.reset_api_client! }
69
-
70
- it 'is possible to set timeouts' do
71
- allow(LokaliseRails).to receive(:timeouts).and_return({
72
- open_timeout: 100,
73
- timeout: 500
74
- })
75
-
76
- expect(described_class.api_client).to be_an_instance_of(Lokalise::Client)
77
- expect(described_class.api_client.open_timeout).to eq(100)
78
- expect(described_class.api_client.timeout).to eq(500)
79
- end
80
- end
81
- end
@@ -1,200 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- describe LokaliseRails::TaskDefinition::Exporter do
6
- let(:filename) { 'en.yml' }
7
- let(:path) { "#{Rails.root}/config/locales/nested/#{filename}" }
8
- let(:relative_name) { "nested/#{filename}" }
9
-
10
- context 'with many translation files' do
11
- let(:fake_class) { described_class }
12
-
13
- before :all do
14
- add_translation_files! with_ru: true, additional: 5
15
- end
16
-
17
- after :all do
18
- rm_translation_files
19
- end
20
-
21
- describe '.export!' do
22
- it 'sends a proper API request and handles rate limiting' do
23
- allow_project_id '672198945b7d72fc048021.15940510'
24
-
25
- process = VCR.use_cassette('upload_files_multiple') do
26
- described_class.export!
27
- end.first
28
-
29
- expect(process.project_id).to eq(LokaliseRails.project_id)
30
- expect(process.status).to eq('queued')
31
- end
32
-
33
- it 'handles too many requests' do
34
- allow_project_id '672198945b7d72fc048021.15940510'
35
- allow(LokaliseRails).to receive(:max_retries_export).and_return(2)
36
-
37
- fake_client = double
38
- allow(fake_client).to receive(:upload_file).and_raise(Lokalise::Error::TooManyRequests)
39
- allow(fake_class).to receive(:api_client).and_return(fake_client)
40
-
41
- expect(-> { fake_class.export! }).to raise_error(Lokalise::Error::TooManyRequests, /Gave up after 2 retries/i)
42
- expect(LokaliseRails).to have_received(:max_retries_export).exactly(1).times
43
- expect(fake_class).to have_received(:api_client).exactly(3).times
44
- expect(fake_client).to have_received(:upload_file).exactly(3).times
45
- end
46
- end
47
- end
48
-
49
- context 'with one translation file' do
50
- before :all do
51
- add_translation_files!
52
- end
53
-
54
- after :all do
55
- rm_translation_files
56
- end
57
-
58
- describe '.export!' do
59
- it 'sends a proper API request' do
60
- allow_project_id
61
-
62
- process = VCR.use_cassette('upload_files') do
63
- described_class.export!
64
- end.first
65
-
66
- expect(process.project_id).to eq(LokaliseRails.project_id)
67
- expect(process.status).to eq('queued')
68
- expect(LokaliseRails.max_retries_export).to eq(5)
69
- end
70
-
71
- it 'sends a proper API request when a different branch is provided' do
72
- allow_project_id
73
- allow(LokaliseRails).to receive(:branch).and_return('develop')
74
-
75
- process = VCR.use_cassette('upload_files_branch') do
76
- described_class.export!
77
- end.first
78
-
79
- expect(LokaliseRails).to have_received(:branch)
80
- expect(process.project_id).to eq(LokaliseRails.project_id)
81
- expect(process.status).to eq('queued')
82
- end
83
-
84
- it 'halts when the API key is not set' do
85
- allow(LokaliseRails).to receive(:api_token).and_return(nil)
86
-
87
- expect(-> { described_class.export! }).to raise_error(LokaliseRails::Error, /API token is not set/i)
88
- expect(LokaliseRails).to have_received(:api_token)
89
- end
90
-
91
- it 'halts when the project_id is not set' do
92
- allow_project_id nil do
93
- expect(-> { described_class.export! }).to raise_error(LokaliseRails::Error, /ID is not set/i)
94
- end
95
- end
96
- end
97
-
98
- describe '.each_file' do
99
- it 'yield proper arguments' do
100
- expect { |b| described_class.each_file(&b) }.to yield_with_args(
101
- Pathname.new(path),
102
- Pathname.new(relative_name)
103
- )
104
- end
105
- end
106
-
107
- describe '.opts' do
108
- let(:base64content) { Base64.strict_encode64(File.read(path).strip) }
109
-
110
- it 'generates proper options' do
111
- resulting_opts = described_class.opts(path, relative_name)
112
-
113
- expect(resulting_opts[:data]).to eq(base64content)
114
- expect(resulting_opts[:filename]).to eq(relative_name)
115
- expect(resulting_opts[:lang_iso]).to eq('en')
116
- end
117
-
118
- it 'allows to redefine options' do
119
- allow(LokaliseRails).to receive(:export_opts).and_return({
120
- detect_icu_plurals: true,
121
- convert_placeholders: true
122
- })
123
-
124
- resulting_opts = described_class.opts(path, relative_name)
125
-
126
- expect(LokaliseRails).to have_received(:export_opts)
127
- expect(resulting_opts[:data]).to eq(base64content)
128
- expect(resulting_opts[:filename]).to eq(relative_name)
129
- expect(resulting_opts[:lang_iso]).to eq('en')
130
- expect(resulting_opts[:detect_icu_plurals]).to be true
131
- expect(resulting_opts[:convert_placeholders]).to be true
132
- end
133
- end
134
- end
135
-
136
- context 'with two translation files' do
137
- let(:filename_ru) { 'ru.yml' }
138
- let(:path_ru) { "#{Rails.root}/config/locales/#{filename_ru}" }
139
- let(:relative_name_ru) { filename_ru }
140
-
141
- before :all do
142
- add_translation_files! with_ru: true
143
- end
144
-
145
- after :all do
146
- rm_translation_files
147
- end
148
-
149
- describe '.export!' do
150
- it 're-raises export errors' do
151
- allow_project_id
152
-
153
- VCR.use_cassette('upload_files_error') do
154
- expect { described_class.export! }.to raise_error(Lokalise::Error::BadRequest, /Unknown `lang_iso`/)
155
- end
156
- end
157
- end
158
-
159
- describe '.opts' do
160
- let(:base64content_ru) { Base64.strict_encode64(File.read(path_ru).strip) }
161
-
162
- it 'generates proper options' do
163
- resulting_opts = described_class.opts(path_ru, relative_name_ru)
164
-
165
- expect(resulting_opts[:data]).to eq(base64content_ru)
166
- expect(resulting_opts[:filename]).to eq(relative_name_ru)
167
- expect(resulting_opts[:lang_iso]).to eq('ru_RU')
168
- end
169
- end
170
-
171
- describe '.each_file' do
172
- it 'yields every translation file' do
173
- expect { |b| described_class.each_file(&b) }.to yield_successive_args(
174
- [
175
- Pathname.new(path),
176
- Pathname.new(relative_name)
177
- ],
178
- [
179
- Pathname.new(path_ru),
180
- Pathname.new(relative_name_ru)
181
- ]
182
- )
183
- end
184
-
185
- it 'does not yield files that have to be skipped' do
186
- allow(LokaliseRails).to receive(:skip_file_export).twice.and_return(
187
- ->(f) { f.split[1].to_s.include?('ru') }
188
- )
189
- expect { |b| described_class.each_file(&b) }.to yield_successive_args(
190
- [
191
- Pathname.new(path),
192
- Pathname.new(relative_name)
193
- ]
194
- )
195
-
196
- expect(LokaliseRails).to have_received(:skip_file_export).twice
197
- end
198
- end
199
- end
200
- end