lokalise_manager 3.0.0 → 3.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f68d621f5413a53e386f1d1f1539e8f824f6f3e90e81c0fb93c71e9e1c271c9a
4
- data.tar.gz: ecaf5166531cb24f7fa6162ea11d86f885ead2e911f40543cdd08e717e9731e4
3
+ metadata.gz: 71731c95118ae4f31be9e82b256aa2cc17094a0ab64b5a186b95cb37843fec52
4
+ data.tar.gz: d8cbbfd4d60926f2f62323e0908addacf218425fc7e2b579d2f748d0e9acdf93
5
5
  SHA512:
6
- metadata.gz: 659795e4573dab1751fa00b7d23ed43d6c9b276561fc763341b9a2d72dabadb9e8eeb638a7888d4f736b42e49efcb75a627d12c3b5bc63c9a46f369077dacb2c
7
- data.tar.gz: f3681cca401d48512786731538697a2dcac4a7f47ab8d7037a6ce9444308dc4ab71ee34220218654dc71823c1d1a0b3945494015f6f822ac089ca87627a92d1d
6
+ metadata.gz: d457a5a7e4f703b80c3780e1a35e75278671c78f9caa0464bb0488352fa2772500e9f4f921446f8a3b51e9240fd229b1935705ba5b86263cb9e20bd27eab274d
7
+ data.tar.gz: 7053cf881bee4814dd67f17238557f7e19a0f6dc96109cf88700845018110c083612477eb15b49643d2459332d7e6abbd705cfe9322d36aa4735d7e73bcf887c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.1.0 (17-Aug-22)
4
+
5
+ * The default format is now `ruby_yaml` (it used to be `yaml`)
6
+
3
7
  ## 3.0.0 (11-Mar-22)
4
8
 
5
9
  * **Breaking change**: Require Ruby 2.7 or above
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Lokalise team, Ilya Bodrov
3
+ Copyright (c) 2022 Lokalise team, Ilya Krukowski
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -111,7 +111,7 @@ Please don't forget that Lokalise API has rate limiting and you cannot send more
111
111
 
112
112
  ```ruby
113
113
  {
114
- format: 'yaml',
114
+ format: 'ruby_yaml',
115
115
  placeholder_format: :icu,
116
116
  yaml_include_root: true,
117
117
  original_filenames: true,
@@ -120,7 +120,7 @@ Please don't forget that Lokalise API has rate limiting and you cannot send more
120
120
  }
121
121
  ```
122
122
 
123
- Full list of available import options [can be found in the official API documentation](https://app.lokalise.com/api2docs/curl/#transition-download-files-post).
123
+ Full list of available import options [can be found in the official API documentation](https://developers.lokalise.com/reference/download-files).
124
124
 
125
125
  You can provide additional options, and they will be merged with the default ones. For example:
126
126
 
@@ -135,7 +135,7 @@ In this case the `import_opts` will have `original_filenames` set to `true` and
135
135
  ```ruby
136
136
  importer = LokaliseManager.importer api_token: '1234abc',
137
137
  project_id: '123.abc',
138
- import_opts: {indentation: '4sp}
138
+ import_opts: {indentation: '4sp'}
139
139
  ```
140
140
 
141
141
  * `import_safe_mode` (`boolean`) — default to `false`. When this option is enabled, the import task will check whether the directory set with `locales_path` is empty or not. If it is not empty, you will be prompted to continue.
@@ -143,7 +143,7 @@ importer = LokaliseManager.importer api_token: '1234abc',
143
143
 
144
144
  ### Export config
145
145
 
146
- * `export_opts` (`hash`) — options that will be passed to Lokalise API when uploading translations. Full list of available export options [can be found in the official documentation](https://app.lokalise.com/api2docs/curl/#transition-upload-a-file-post). By default, the following options are provided:
146
+ * `export_opts` (`hash`) — options that will be passed to Lokalise API when uploading translations. Full list of available export options [can be found in the official documentation](https://developers.lokalise.com/reference/upload-a-file). By default, the following options are provided:
147
147
  + `data` (`string`, required) — base64-encoded contents of the translation file.
148
148
  + `filename` (`string`, required) — translation file name. If the file is stored under a subdirectory (for example, `nested/en.yml` inside the `locales/` directory), the whole path acts as a name. Later when importing files with such names, they will be placed into the proper subdirectories.
149
149
  + `lang_iso` (`string`, required) — language ISO code which is determined using the root key inside your YAML file. For example, in this case the `lang_iso` is `en_US`:
@@ -302,4 +302,4 @@ importer.import!
302
302
 
303
303
  ## License
304
304
 
305
- Copyright (c) [Lokalise team](http://lokalise.com), [Ilya Bodrov](http://bodrovis.tech). License type is [MIT](https://github.com/bodrovis/lokalise_manager/blob/master/LICENSE).
305
+ Copyright (c) [Lokalise team](http://lokalise.com), [Ilya Krukowski](http://bodrovis.tech). License type is [MIT](https://github.com/bodrovis/lokalise_manager/blob/master/LICENSE).
@@ -65,7 +65,7 @@ module LokaliseManager
65
65
  # Options for import rake task
66
66
  def import_opts
67
67
  @import_opts || {
68
- format: 'yaml',
68
+ format: 'ruby_yaml',
69
69
  placeholder_format: :icu,
70
70
  yaml_include_root: true,
71
71
  original_filenames: true,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LokaliseManager
4
- VERSION = '3.0.0'
4
+ VERSION = '3.1.0'
5
5
  end
@@ -5,7 +5,7 @@ require File.expand_path('lib/lokalise_manager/version', __dir__)
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'lokalise_manager'
7
7
  spec.version = LokaliseManager::VERSION
8
- spec.authors = ['Ilya Bodrov']
8
+ spec.authors = ['Ilya Krukowski']
9
9
  spec.email = ['golosizpru@gmail.com']
10
10
  spec.summary = 'Lokalise integration for Ruby'
11
11
  spec.description = 'This gem contains a collection of some common tasks for Lokalise. Specifically, it allows to import/export translation files from/to Lokalise TMS.'
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
19
19
  'lib/**/*.rake',
20
20
  'lokalise_manager.gemspec', '.github/*.md',
21
21
  'Gemfile', 'Rakefile']
22
- spec.test_files = Dir['spec/**/*.rb']
23
22
  spec.extra_rdoc_files = ['README.md']
24
23
  spec.require_paths = ['lib']
25
24
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lokalise_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Ilya Bodrov
7
+ - Ilya Krukowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-11 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-lokalise-api
@@ -204,16 +204,6 @@ files:
204
204
  - lib/lokalise_manager/utils/hash_utils.rb
205
205
  - lib/lokalise_manager/version.rb
206
206
  - lokalise_manager.gemspec
207
- - spec/lib/lokalise_manager/global_config_spec.rb
208
- - spec/lib/lokalise_manager/task_definitions/base_spec.rb
209
- - spec/lib/lokalise_manager/task_definitions/exporter_spec.rb
210
- - spec/lib/lokalise_manager/task_definitions/importer_spec.rb
211
- - spec/lib/lokalise_manager/utils/hash_utils_spec.rb
212
- - spec/lib/lokalise_manager_spec.rb
213
- - spec/spec_helper.rb
214
- - spec/support/file_manager.rb
215
- - spec/support/spec_addons.rb
216
- - spec/support/vcr.rb
217
207
  homepage: https://github.com/bodrovis/lokalise_manager
218
208
  licenses:
219
209
  - MIT
@@ -234,18 +224,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
224
  - !ruby/object:Gem::Version
235
225
  version: '0'
236
226
  requirements: []
237
- rubygems_version: 3.3.8
227
+ rubygems_version: 3.3.19
238
228
  signing_key:
239
229
  specification_version: 4
240
230
  summary: Lokalise integration for Ruby
241
- test_files:
242
- - spec/lib/lokalise_manager/global_config_spec.rb
243
- - spec/lib/lokalise_manager/task_definitions/base_spec.rb
244
- - spec/lib/lokalise_manager/task_definitions/exporter_spec.rb
245
- - spec/lib/lokalise_manager/task_definitions/importer_spec.rb
246
- - spec/lib/lokalise_manager/utils/hash_utils_spec.rb
247
- - spec/lib/lokalise_manager_spec.rb
248
- - spec/spec_helper.rb
249
- - spec/support/file_manager.rb
250
- - spec/support/spec_addons.rb
251
- - spec/support/vcr.rb
231
+ test_files: []
@@ -1,114 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe LokaliseManager::GlobalConfig do
4
- let(:fake_class) { class_double(described_class) }
5
-
6
- it 'is possible to provide config' do
7
- described_class.config do |c|
8
- expect(c).to eq(described_class)
9
- end
10
- end
11
-
12
- it 'is possible to set project_id' do
13
- allow(fake_class).to receive(:project_id=).with('123.abc')
14
- fake_class.project_id = '123.abc'
15
- end
16
-
17
- it 'is possible to set raise_on_export_fail' do
18
- allow(fake_class).to receive(:raise_on_export_fail=).with(false)
19
- fake_class.raise_on_export_fail = false
20
- end
21
-
22
- it 'is possible to set silent_mode' do
23
- allow(fake_class).to receive(:silent_mode=).with(true)
24
- fake_class.silent_mode = true
25
- end
26
-
27
- it 'is possible to set use_oauth2_token' do
28
- allow(fake_class).to receive(:use_oauth2_token=).with(true)
29
- fake_class.use_oauth2_token = true
30
- end
31
-
32
- it 'is possible to set file_ext_regexp' do
33
- allow(fake_class).to receive(:file_ext_regexp=).with(Regexp.new('.*'))
34
- fake_class.file_ext_regexp = Regexp.new('.*')
35
- end
36
-
37
- it 'is possible to set import_opts' do
38
- allow(fake_class).to receive(:import_opts=).with(duck_type(:each))
39
- fake_class.import_opts = {
40
- format: 'json',
41
- indentation: '8sp'
42
- }
43
- end
44
-
45
- it 'is possible to set export_opts' do
46
- allow(fake_class).to receive(:export_opts=).with(duck_type(:each))
47
- fake_class.export_opts = {
48
- convert_placeholders: true,
49
- detect_icu_plurals: true
50
- }
51
- end
52
-
53
- it 'is possible to set branch' do
54
- allow(fake_class).to receive(:branch=).with('custom')
55
- fake_class.branch = 'custom'
56
- end
57
-
58
- it 'is possible to set timeouts' do
59
- allow(fake_class).to receive(:timeouts=).with(duck_type(:each))
60
- fake_class.timeouts = {
61
- open_timeout: 100,
62
- timeout: 500
63
- }
64
- end
65
-
66
- it 'is possible to set import_safe_mode' do
67
- allow(fake_class).to receive(:import_safe_mode=).with(true)
68
- fake_class.import_safe_mode = true
69
- end
70
-
71
- it 'is possible to set max_retries_export' do
72
- allow(fake_class).to receive(:max_retries_export=).with(10)
73
- fake_class.max_retries_export = 10
74
- end
75
-
76
- it 'is possible to set max_retries_import' do
77
- allow(fake_class).to receive(:max_retries_import=).with(10)
78
- fake_class.max_retries_import = 10
79
- end
80
-
81
- it 'is possible to set api_token' do
82
- allow(fake_class).to receive(:api_token=).with('abc')
83
- fake_class.api_token = 'abc'
84
- end
85
-
86
- it 'is possible to override locales_path' do
87
- allow(fake_class).to receive(:locales_path=).with('/demo/path')
88
- fake_class.locales_path = '/demo/path'
89
- end
90
-
91
- it 'is possible to set skip_file_export' do
92
- cond = ->(f) { f.nil? }
93
- allow(fake_class).to receive(:skip_file_export=).with(cond)
94
- fake_class.skip_file_export = cond
95
- end
96
-
97
- it 'is possible to set translations_loader' do
98
- runner = ->(f) { f.to_json }
99
- allow(fake_class).to receive(:translations_loader=).with(runner)
100
- fake_class.translations_loader = runner
101
- end
102
-
103
- it 'is possible to set translations_converter' do
104
- runner = ->(f) { f.to_json }
105
- allow(fake_class).to receive(:translations_converter=).with(runner)
106
- fake_class.translations_converter = runner
107
- end
108
-
109
- it 'is possible to set lang_iso_inferer' do
110
- runner = ->(f) { f.to_json }
111
- allow(fake_class).to receive(:lang_iso_inferer=).with(runner)
112
- fake_class.lang_iso_inferer = runner
113
- end
114
- end
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe LokaliseManager::TaskDefinitions::Base do
4
- let(:described_object) { described_class.new }
5
-
6
- describe '.new' do
7
- it 'allows to override config' do
8
- obj = described_class.new token: 'fake'
9
- expect(obj.config.token).to eq('fake')
10
- end
11
- end
12
-
13
- describe '#config' do
14
- it 'allows to update config after initialization' do
15
- obj = described_class.new token: 'fake', project_id: '123'
16
-
17
- obj.config.project_id = '345'
18
-
19
- expect(obj.config.project_id).to eq('345')
20
- expect(obj.config.token).to eq('fake')
21
- end
22
- end
23
-
24
- specify '.reset_client!' do
25
- expect(described_object.api_client).to be_an_instance_of(RubyLokaliseApi::Client)
26
- described_object.reset_api_client!
27
- current_client = described_object.instance_variable_get :@api_client
28
- expect(current_client).to be_nil
29
- end
30
-
31
- specify '.project_id_with_branch!' do
32
- result = described_object.send :project_id_with_branch
33
- expect(result).to be_an_instance_of(String)
34
- expect(result).not_to include(':master')
35
-
36
- described_object.config.branch = 'develop'
37
- result = described_object.send :project_id_with_branch
38
- expect(result).to be_an_instance_of(String)
39
- expect(result).to include(':develop')
40
- end
41
-
42
- describe '.subdir_and_filename_for' do
43
- it 'works properly for longer paths' do
44
- path = 'my_path/is/here/file.yml'
45
- result = described_object.send(:subdir_and_filename_for, path)
46
- expect(result.length).to eq(2)
47
- expect(result[0]).to be_an_instance_of(Pathname)
48
- expect(result[0].to_s).to eq('my_path/is/here')
49
- expect(result[1].to_s).to eq('file.yml')
50
- end
51
-
52
- it 'works properly for shorter paths' do
53
- path = 'file.yml'
54
- result = described_object.send(:subdir_and_filename_for, path)
55
- expect(result.length).to eq(2)
56
- expect(result[1]).to be_an_instance_of(Pathname)
57
- expect(result[0].to_s).to eq('.')
58
- expect(result[1].to_s).to eq('file.yml')
59
- end
60
- end
61
-
62
- describe '.check_options_errors!' do
63
- it 'raises an error when the API key is not set' do
64
- allow(LokaliseManager::GlobalConfig).to receive(:api_token).and_return(nil)
65
-
66
- expect do
67
- described_object.send(:check_options_errors!)
68
- end.to raise_error(LokaliseManager::Error, /API token is not set/i)
69
-
70
- expect(LokaliseManager::GlobalConfig).to have_received(:api_token)
71
- end
72
-
73
- it 'returns an error when the project_id is not set' do
74
- allow_project_id described_object, nil do
75
- expect do
76
- described_object.send(:check_options_errors!)
77
- end.to raise_error(LokaliseManager::Error, /ID is not set/i)
78
- end
79
- end
80
- end
81
-
82
- describe '.proper_ext?' do
83
- it 'works properly with path represented as a string' do
84
- path = 'my_path/here/file.yml'
85
- expect(described_object.send(:proper_ext?, path)).to be true
86
- end
87
-
88
- it 'works properly with path represented as a pathname' do
89
- path = Pathname.new 'my_path/here/file.json'
90
- expect(described_object.send(:proper_ext?, path)).to be false
91
- end
92
- end
93
-
94
- describe '.api_client' do
95
- it 'is possible to set timeouts' do
96
- allow(described_object.config).to receive(:timeouts).and_return({
97
- open_timeout: 100,
98
- timeout: 500
99
- })
100
-
101
- client = described_object.api_client
102
- expect(client).to be_an_instance_of(RubyLokaliseApi::Client)
103
- expect(client).not_to be_an_instance_of(RubyLokaliseApi::OAuth2Client)
104
- expect(client.open_timeout).to eq(100)
105
- expect(client.timeout).to eq(500)
106
- end
107
-
108
- it 'uses .oauth_client when the use_oauth2_token is true' do
109
- allow(described_object.config).to receive(:use_oauth2_token).and_return(true)
110
-
111
- client = described_object.api_client
112
-
113
- expect(client).to be_an_instance_of(RubyLokaliseApi::OAuth2Client)
114
- expect(client).not_to be_an_instance_of(RubyLokaliseApi::Client)
115
- end
116
- end
117
- end
@@ -1,273 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
-
5
- describe LokaliseManager::TaskDefinitions::Exporter do
6
- let(:filename) { 'en.yml' }
7
- let(:path) { "#{Dir.getwd}/locales/nested/#{filename}" }
8
- let(:relative_name) { "nested/#{filename}" }
9
- let(:project_id) { ENV['LOKALISE_PROJECT_ID'] }
10
- let(:described_object) do
11
- described_class.new project_id: project_id,
12
- api_token: ENV['LOKALISE_API_TOKEN'],
13
- max_retries_export: 2
14
- end
15
-
16
- context 'with many translation files' do
17
- describe '.export!' do
18
- context 'with no errors' do
19
- before do
20
- add_translation_files! with_ru: true, additional: 5
21
- end
22
-
23
- after do
24
- rm_translation_files
25
- end
26
-
27
- it 'sends a proper API request and handles rate limiting' do
28
- process = nil
29
-
30
- VCR.use_cassette('upload_files_multiple') do
31
- expect { process = described_object.export!.first.process }.to output(/complete!/).to_stdout
32
- end
33
-
34
- expect(process.project_id).to eq(project_id)
35
- expect(process.status).to eq('queued')
36
- end
37
-
38
- it 'handles too many requests but does not re-raise anything when raise_on_export_fail is false' do
39
- allow(described_object.config).to receive(:max_retries_export).and_return(1)
40
- allow(described_object.config).to receive(:raise_on_export_fail).and_return(false)
41
- allow(described_object).to receive(:sleep).and_return(0)
42
-
43
- fake_client = instance_double('RubyLokaliseApi::Client')
44
- allow(fake_client).to receive(:token).with(any_args).and_return('fake_token')
45
- allow(fake_client).to receive(:upload_file).with(any_args).and_raise(RubyLokaliseApi::Error::TooManyRequests)
46
- allow(described_object).to receive(:api_client).and_return(fake_client)
47
- processes = []
48
- expect { processes = described_object.export! }.not_to raise_error
49
-
50
- expect(processes[0].success).to be false
51
- expect(processes[1].error.class).to eq(RubyLokaliseApi::Error::TooManyRequests)
52
- expect(processes.count).to eq(7)
53
-
54
- expect(described_object).to have_received(:sleep).exactly(7).times
55
- expect(described_object).to have_received(:api_client).at_least(14).times
56
- expect(fake_client).to have_received(:upload_file).exactly(14).times
57
- end
58
- end
59
-
60
- context 'with errors' do
61
- before do
62
- add_translation_files! with_ru: true
63
- end
64
-
65
- after do
66
- rm_translation_files
67
- end
68
-
69
- it 'handles too many requests' do
70
- allow(described_object.config).to receive(:max_retries_export).and_return(1)
71
- allow(described_object).to receive(:sleep).and_return(0)
72
-
73
- fake_client = instance_double('RubyLokaliseApi::Client')
74
- allow(fake_client).to receive(:token).with(any_args).and_return('fake_token')
75
- allow(fake_client).to receive(:upload_file).with(any_args).and_raise(RubyLokaliseApi::Error::TooManyRequests)
76
- allow(described_object).to receive(:api_client).and_return(fake_client)
77
-
78
- expect do
79
- described_object.export!
80
- end.to raise_error(RubyLokaliseApi::Error::TooManyRequests, /Gave up after 1 retries/i)
81
-
82
- expect(described_object).to have_received(:sleep).exactly(2).times
83
- expect(described_object).to have_received(:api_client).at_least(4).times
84
- expect(fake_client).to have_received(:upload_file).exactly(4).times
85
- end
86
- end
87
- end
88
- end
89
-
90
- context 'with one translation file' do
91
- context 'without files' do
92
- it 'halts when the API key is not set' do
93
- allow(described_object.config).to receive(:api_token).and_return(nil)
94
-
95
- expect { described_object.export! }.to raise_error(LokaliseManager::Error, /API token is not set/i)
96
- expect(described_object.config).to have_received(:api_token)
97
- end
98
-
99
- it 'halts when the project_id is not set' do
100
- allow_project_id described_object, nil do
101
- expect { described_object.export! }.to raise_error(LokaliseManager::Error, /ID is not set/i)
102
- end
103
- end
104
- end
105
-
106
- context 'with files' do
107
- before do
108
- add_translation_files!
109
- end
110
-
111
- after do
112
- rm_translation_files
113
- end
114
-
115
- describe '.export!' do
116
- it 'sends a proper API request but does not output anything when silent_mode is enabled' do
117
- allow(described_object.config).to receive(:silent_mode).and_return(true)
118
-
119
- process = nil
120
-
121
- VCR.use_cassette('upload_files') do
122
- expect { process = described_object.export!.first.process }.not_to output(/complete!/).to_stdout
123
- end
124
-
125
- expect(process.status).to eq('queued')
126
- expect(described_object.config).to have_received(:silent_mode).at_most(1).times
127
- end
128
-
129
- it 'sends a proper API request' do
130
- process = VCR.use_cassette('upload_files') do
131
- described_object.export!
132
- end.first.process
133
-
134
- expect(process.project_id).to eq(project_id)
135
- expect(process.status).to eq('queued')
136
- end
137
-
138
- it 'sends a proper API request when a different branch is provided' do
139
- allow(described_object.config).to receive(:branch).and_return('develop')
140
-
141
- process_data = VCR.use_cassette('upload_files_branch') do
142
- described_object.export!
143
- end.first
144
-
145
- expect(described_object.config).to have_received(:branch).at_most(2).times
146
- expect(process_data.success).to be true
147
- expect(process_data.path.to_s).to include('en.yml')
148
-
149
- process = process_data.process
150
- expect(process).to be_an_instance_of(RubyLokaliseApi::Resources::QueuedProcess)
151
- expect(process.project_id).to eq(project_id)
152
- expect(process.status).to eq('queued')
153
- end
154
- end
155
- end
156
-
157
- describe '#all_files' do
158
- before do
159
- add_translation_files!
160
- end
161
-
162
- after do
163
- rm_translation_files
164
- end
165
-
166
- it 'yield proper arguments' do
167
- expect(described_object.send(:all_files).flatten).to include(
168
- Pathname.new(path),
169
- Pathname.new(relative_name)
170
- )
171
- end
172
- end
173
-
174
- describe '.opts' do
175
- before do
176
- add_translation_files!
177
- end
178
-
179
- after do
180
- rm_translation_files
181
- end
182
-
183
- let(:base64content) { Base64.strict_encode64(File.read(path).strip) }
184
-
185
- it 'generates proper options' do
186
- resulting_opts = described_object.send(:opts, path, relative_name)
187
-
188
- expect(resulting_opts[:data]).to eq(base64content)
189
- expect(resulting_opts[:filename]).to eq(relative_name)
190
- expect(resulting_opts[:lang_iso]).to eq('en')
191
- end
192
-
193
- it 'allows to redefine options' do
194
- allow(described_object.config).to receive(:export_opts).and_return({
195
- detect_icu_plurals: true,
196
- convert_placeholders: true
197
- })
198
-
199
- resulting_opts = described_object.send(:opts, path, relative_name)
200
-
201
- expect(described_object.config).to have_received(:export_opts)
202
- expect(resulting_opts[:data]).to eq(base64content)
203
- expect(resulting_opts[:filename]).to eq(relative_name)
204
- expect(resulting_opts[:lang_iso]).to eq('en')
205
- expect(resulting_opts[:detect_icu_plurals]).to be true
206
- expect(resulting_opts[:convert_placeholders]).to be true
207
- end
208
- end
209
- end
210
-
211
- context 'with two translation files' do
212
- let(:filename_ru) { 'ru.yml' }
213
- let(:path_ru) { "#{Dir.getwd}/locales/#{filename_ru}" }
214
-
215
- before do
216
- add_translation_files! with_ru: true
217
- end
218
-
219
- after do
220
- rm_translation_files
221
- end
222
-
223
- describe '.export!' do
224
- it 're-raises export errors' do
225
- allow_project_id described_object, '542886116159f798720dc4.94769464'
226
-
227
- VCR.use_cassette('upload_files_error') do
228
- expect { described_object.export! }.to raise_error(RubyLokaliseApi::Error::BadRequest, /Unknown `lang_iso`/)
229
- end
230
- end
231
- end
232
-
233
- describe '.opts' do
234
- let(:base64content_ru) { Base64.strict_encode64(File.read(path_ru).strip) }
235
-
236
- it 'generates proper options' do
237
- resulting_opts = described_object.send(:opts, path_ru, filename_ru)
238
-
239
- expect(resulting_opts[:data]).to eq(base64content_ru)
240
- expect(resulting_opts[:filename]).to eq(filename_ru)
241
- expect(resulting_opts[:lang_iso]).to eq('ru_RU')
242
- end
243
- end
244
-
245
- describe '#all_files' do
246
- it 'returns all files' do
247
- files = described_object.send(:all_files).flatten
248
- expect(files).to include(
249
- Pathname.new(path),
250
- Pathname.new(relative_name)
251
- )
252
- expect(files).to include(
253
- Pathname.new(path_ru),
254
- Pathname.new(filename_ru)
255
- )
256
- end
257
-
258
- it 'does not return files that have to be skipped' do
259
- allow(described_object.config).to receive(:skip_file_export).twice.and_return(
260
- ->(f) { f.split[1].to_s.include?('ru') }
261
- )
262
- files = described_object.send(:all_files).sort
263
- expect(files[0]).to include(
264
- Pathname.new(path),
265
- Pathname.new(relative_name)
266
- )
267
- expect(files.count).to eq(1)
268
-
269
- expect(described_object.config).to have_received(:skip_file_export).twice
270
- end
271
- end
272
- end
273
- end
@@ -1,195 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe LokaliseManager::TaskDefinitions::Importer do
4
- let(:described_object) do
5
- described_class.new project_id: project_id,
6
- api_token: ENV['LOKALISE_API_TOKEN'],
7
- max_retries_import: 2
8
- end
9
- let(:loc_path) { described_object.config.locales_path }
10
- let(:project_id) { ENV['LOKALISE_PROJECT_ID'] }
11
- let(:local_trans) { "#{Dir.getwd}/spec/fixtures/trans.zip" }
12
-
13
- describe '#open_and_process_zip' do
14
- it 're-raises errors during file processing' do
15
- entry = double
16
- allow(entry).to receive(:name).and_return('fail.yml')
17
- allow(described_object).to receive(:data_from).with(entry).and_raise(EncodingError)
18
- expect { described_object.send(:process!, entry) }.
19
- to raise_error(EncodingError, /Error when trying to process fail\.yml/)
20
-
21
- expect(described_object).to have_received(:data_from)
22
- end
23
-
24
- it 're-raises errors during file opening' do
25
- expect { described_object.send(:open_and_process_zip, 'http://fake.url/wrong/path.zip') }.
26
- to raise_error(SocketError, /Failed to open TCP connection/)
27
- end
28
- end
29
-
30
- describe '#download_files' do
31
- it 'returns a proper download URL' do
32
- response = VCR.use_cassette('download_files') do
33
- described_object.send :download_files
34
- end
35
-
36
- expect(response['project_id']).to eq('672198945b7d72fc048021.15940510')
37
- expect(response['bundle_url']).to include('s3-eu-west-1.amazonaws.com')
38
- end
39
-
40
- it 're-raises errors during file download' do
41
- allow_project_id described_object, 'invalid'
42
-
43
- VCR.use_cassette('download_files_error') do
44
- expect { described_object.send :download_files }.
45
- to raise_error(RubyLokaliseApi::Error::BadRequest, /Invalid `project_id` parameter/)
46
- end
47
- end
48
- end
49
-
50
- describe '.import!' do
51
- context 'with errors' do
52
- it 'handles too many requests' do
53
- allow(described_object).to receive(:sleep).and_return(0)
54
-
55
- fake_client = instance_double('RubyLokaliseApi::Client')
56
- allow(fake_client).to receive(:download_files).and_raise(RubyLokaliseApi::Error::TooManyRequests)
57
- allow(described_object).to receive(:api_client).and_return(fake_client)
58
-
59
- expect { described_object.import! }.to raise_error(RubyLokaliseApi::Error::TooManyRequests, /Gave up after 2 retries/i)
60
-
61
- expect(described_object).to have_received(:sleep).exactly(2).times
62
- expect(described_object).to have_received(:api_client).exactly(3).times
63
- expect(fake_client).to have_received(:download_files).exactly(3).times
64
- end
65
-
66
- it 'halts when the API key is not set' do
67
- allow(described_object.config).to receive(:api_token).and_return(nil)
68
- expect { described_object.import! }.to raise_error(LokaliseManager::Error, /API token is not set/i)
69
- expect(described_object.config).to have_received(:api_token)
70
- expect(count_translations).to eq(0)
71
- end
72
-
73
- it 'halts when the project_id is not set' do
74
- allow_project_id described_object, nil do
75
- expect { described_object.import! }.to raise_error(LokaliseManager::Error, /ID is not set/i)
76
- expect(count_translations).to eq(0)
77
- end
78
- end
79
- end
80
-
81
- context 'when directory is empty' do
82
- before do
83
- mkdir_locales
84
- end
85
-
86
- after do
87
- rm_translation_files
88
- end
89
-
90
- it 'runs import successfully for local files' do
91
- allow(described_object).to receive(:download_files).and_return(
92
- {
93
- 'project_id' => '123.abc',
94
- 'bundle_url' => local_trans
95
- }
96
- )
97
-
98
- expect(described_object.import!).to be true
99
-
100
- expect(count_translations).to eq(4)
101
- expect(described_object).to have_received(:download_files)
102
- expect_file_exist loc_path, 'en/nested/main_en.yml'
103
- expect_file_exist loc_path, 'en/nested/deep/secondary_en.yml'
104
- expect_file_exist loc_path, 'ru/main_ru.yml'
105
- end
106
-
107
- it 'runs import successfully' do
108
- result = nil
109
-
110
- VCR.use_cassette('import') do
111
- expect { result = described_object.import! }.to output(/complete!/).to_stdout
112
- end
113
-
114
- expect(result).to be true
115
-
116
- expect(count_translations).to eq(24)
117
- expect_file_exist loc_path, 'en_1.yml'
118
- expect_file_exist loc_path, 'ru_2.yml'
119
- end
120
-
121
- it 'runs import successfully but does not provide any output when silent_mode is enabled' do
122
- allow(described_object.config).to receive(:silent_mode).and_return(true)
123
- result = nil
124
-
125
- VCR.use_cassette('import') do
126
- expect { result = described_object.import! }.not_to output(/complete!/).to_stdout
127
- end
128
-
129
- expect(result).to be true
130
- expect_file_exist loc_path, 'en_1.yml'
131
- expect_file_exist loc_path, 'ru_2.yml'
132
- expect(described_object.config).to have_received(:silent_mode).at_most(1).times
133
- end
134
- end
135
-
136
- context 'when directory is not empty and safe mode enabled' do
137
- let(:safe_mode_obj) do
138
- described_class.new project_id: project_id,
139
- api_token: ENV['LOKALISE_API_TOKEN'],
140
- import_safe_mode: true
141
- end
142
-
143
- before do
144
- mkdir_locales
145
- rm_translation_files
146
- add_translation_files!
147
- end
148
-
149
- after do
150
- rm_translation_files
151
- end
152
-
153
- it 'import proceeds when the user agrees' do
154
- allow(safe_mode_obj).to receive(:download_files).and_return(
155
- {
156
- 'project_id' => '123.abc',
157
- 'bundle_url' => local_trans
158
- }
159
- )
160
-
161
- allow($stdin).to receive(:gets).and_return('Y')
162
- expect { safe_mode_obj.import! }.to output(/is not empty/).to_stdout
163
-
164
- expect(count_translations).to eq(5)
165
- expect($stdin).to have_received(:gets)
166
- expect(safe_mode_obj).to have_received(:download_files)
167
- expect_file_exist loc_path, 'en/nested/main_en.yml'
168
- expect_file_exist loc_path, 'en/nested/deep/secondary_en.yml'
169
- expect_file_exist loc_path, 'ru/main_ru.yml'
170
- end
171
-
172
- it 'import halts when a user chooses not to proceed' do
173
- allow(safe_mode_obj).to receive(:download_files).at_most(0).times
174
- allow($stdin).to receive(:gets).and_return('N')
175
- expect { safe_mode_obj.import! }.to output(/cancelled/).to_stdout
176
-
177
- expect(safe_mode_obj).not_to have_received(:download_files)
178
- expect($stdin).to have_received(:gets)
179
- expect(count_translations).to eq(1)
180
- end
181
-
182
- it 'import halts when a user chooses to halt and debug info is not printed out when silent_mode is enabled' do
183
- allow(safe_mode_obj.config).to receive(:silent_mode).and_return(true)
184
- allow(safe_mode_obj).to receive(:download_files).at_most(0).times
185
- allow($stdin).to receive(:gets).and_return('N')
186
- expect { safe_mode_obj.import! }.not_to output(/cancelled/).to_stdout
187
-
188
- expect(safe_mode_obj).not_to have_received(:download_files)
189
- expect(safe_mode_obj.config).to have_received(:silent_mode)
190
- expect($stdin).to have_received(:gets)
191
- expect(count_translations).to eq(1)
192
- end
193
- end
194
- end
195
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe LokaliseManager::Utils::HashUtils do
4
- using described_class
5
- let(:h1) { {a: 100, b: 200, c: {c1: 100}} }
6
- let(:h2) { {b: 250, c: {c1: 200}} }
7
-
8
- specify '#deep_merge' do
9
- result = h1.deep_merge(h2) { |_key, this_val, other_val| this_val + other_val }
10
- expect(result[:b]).to eq(450)
11
- expect(result[:c][:c1]).to eq(300)
12
- end
13
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe LokaliseManager do
4
- it 'returns a proper version' do
5
- expect(described_class::VERSION).to be_a(String)
6
- end
7
-
8
- specify '.importer' do
9
- expect(described_class.importer).to be_a(LokaliseManager::TaskDefinitions::Importer)
10
- end
11
-
12
- specify '.exporter' do
13
- expect(described_class.exporter).to be_a(LokaliseManager::TaskDefinitions::Exporter)
14
- end
15
- end
data/spec/spec_helper.rb DELETED
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dotenv/load'
4
- require 'simplecov'
5
-
6
- SimpleCov.start do
7
- add_filter 'spec/'
8
- add_filter '.github/'
9
- end
10
-
11
- if ENV['CI'] == 'true'
12
- require 'codecov'
13
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
14
- end
15
-
16
- require 'lokalise_manager'
17
-
18
- # Support files
19
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
20
-
21
- RSpec.configure do |config|
22
- config.include FileManager
23
- config.include SpecAddons
24
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
-
5
- module FileManager
6
- def mkdir_locales
7
- return if File.directory?(LokaliseManager::GlobalConfig.locales_path)
8
-
9
- FileUtils.mkdir_p(LokaliseManager::GlobalConfig.locales_path)
10
- end
11
-
12
- def rm_translation_files
13
- FileUtils.rm_rf locales_dir
14
- end
15
-
16
- def locales_dir
17
- Dir["#{LokaliseManager::GlobalConfig.locales_path}/**/*"]
18
- end
19
-
20
- def count_translations
21
- locales_dir.count { |file| File.file?(file) }
22
- end
23
-
24
- def add_translation_files!(with_ru: false, additional: nil)
25
- FileUtils.mkdir_p "#{Dir.getwd}/locales/nested"
26
- open_and_write('locales/nested/en.yml') { |f| f.write en_data }
27
-
28
- return unless with_ru
29
-
30
- open_and_write('locales/ru.yml') { |f| f.write ru_data }
31
-
32
- return unless additional
33
-
34
- additional.times do |i|
35
- data = {'en' => {"key_#{i}" => "value #{i}"}}
36
-
37
- open_and_write("locales/en_#{i}.yml") { |f| f.write data.to_yaml }
38
- end
39
- end
40
-
41
- def open_and_write(rel_path, &block)
42
- return unless block
43
-
44
- File.open("#{Dir.getwd}/#{rel_path}", 'w+:UTF-8', &block)
45
- end
46
-
47
- private
48
-
49
- def en_data
50
- <<~DATA
51
- en:
52
- my_key: "My value"
53
- nested:
54
- key: "Value 2"
55
- DATA
56
- end
57
-
58
- def ru_data
59
- <<~DATA
60
- ru_RU:
61
- my_key: "Моё значение"
62
- nested:
63
- key: "Значение 2"
64
- DATA
65
- end
66
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpecAddons
4
- def allow_project_id(obj, value)
5
- allow(obj.config).to receive(:project_id).and_return(value)
6
- return unless block_given?
7
-
8
- yield
9
- expect(obj.config).to have_received(:project_id)
10
- end
11
-
12
- def expect_file_exist(path, file)
13
- file_path = File.join path, file
14
- expect(File.file?(file_path)).to be true
15
- end
16
- end
data/spec/support/vcr.rb DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'vcr'
4
-
5
- VCR.configure do |c|
6
- c.ignore_hosts 'codeclimate.com'
7
- c.hook_into :faraday
8
- c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'fixtures', 'vcr_cassettes')
9
- c.filter_sensitive_data('<LOKALISE_TOKEN>') do |_i|
10
- ENV.fetch('LOKALISE_API_TOKEN')
11
- end
12
- c.configure_rspec_metadata!
13
- end