rails_translation_manager 0.1.0 → 1.1.2

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +20 -0
  5. data/Jenkinsfile +3 -1
  6. data/Rakefile +13 -7
  7. data/config/locales/plurals.rb +49 -0
  8. data/lib/rails_translation_manager/cleaner.rb +14 -0
  9. data/lib/rails_translation_manager/i18n_tasks_option_parser.rb +10 -0
  10. data/lib/rails_translation_manager/importer.rb +32 -14
  11. data/lib/rails_translation_manager/locale_checker/all_locales.rb +61 -0
  12. data/lib/rails_translation_manager/locale_checker/base_checker.rb +13 -0
  13. data/lib/rails_translation_manager/locale_checker/incompatible_plurals.rb +79 -0
  14. data/lib/rails_translation_manager/locale_checker/locale_checker_helper.rb +23 -0
  15. data/lib/rails_translation_manager/locale_checker/missing_english_locales.rb +31 -0
  16. data/lib/rails_translation_manager/locale_checker/missing_foreign_locales.rb +31 -0
  17. data/lib/rails_translation_manager/locale_checker/plural_forms.rb +16 -0
  18. data/lib/rails_translation_manager/locale_checker.rb +50 -0
  19. data/lib/rails_translation_manager/version.rb +1 -1
  20. data/lib/rails_translation_manager.rb +21 -3
  21. data/lib/tasks/translation.rake +43 -42
  22. data/rails_translation_manager.gemspec +6 -2
  23. data/spec/locales/cleaner/clean.yml +5 -0
  24. data/spec/locales/cleaner/with_whitespace.yml +5 -0
  25. data/spec/locales/importer/fr.csv +8 -0
  26. data/spec/locales/importer/hy_with_byte_order_mark.csv +4 -0
  27. data/spec/locales/in_sync/cy/browse.yml +12 -0
  28. data/spec/locales/in_sync/en/browse.yml +8 -0
  29. data/spec/locales/out_of_sync/cy.yml +3 -0
  30. data/spec/locales/out_of_sync/en.yml +6 -0
  31. data/spec/rails_translation_manager/cleaner_spec.rb +13 -0
  32. data/spec/rails_translation_manager/importer_spec.rb +93 -0
  33. data/spec/rails_translation_manager/locale_checker/all_locales_spec.rb +24 -0
  34. data/spec/rails_translation_manager/locale_checker/incompatible_plurals_spec.rb +94 -0
  35. data/spec/rails_translation_manager/locale_checker/locale_checker_helper_spec.rb +61 -0
  36. data/spec/rails_translation_manager/locale_checker/missing_english_locales_spec.rb +72 -0
  37. data/spec/rails_translation_manager/locale_checker/missing_foreign_locales_spec.rb +80 -0
  38. data/spec/rails_translation_manager/locale_checker/plural_forms_spec.rb +27 -0
  39. data/spec/rails_translation_manager/locale_checker_spec.rb +68 -0
  40. data/spec/spec_helper.rb +19 -0
  41. data/spec/support/tasks.rb +7 -0
  42. data/spec/tasks/translation_spec.rb +127 -0
  43. data/test/rails_translation_manager/yaml_writer_test.rb +2 -0
  44. data/tmp/.gitkeep +0 -0
  45. metadata +117 -18
  46. data/lib/rails_translation_manager/stealer.rb +0 -85
  47. data/lib/rails_translation_manager/validator.rb +0 -92
  48. data/test/rails_translation_manager/importer_test.rb +0 -132
  49. data/test/rails_translation_manager/stealer_test.rb +0 -251
  50. data/test/rails_translation_manager/validator_test.rb +0 -51
@@ -1,132 +0,0 @@
1
- require "test_helper"
2
- require "rails_translation_manager/importer"
3
- require "tmpdir"
4
- require "csv"
5
-
6
- module RailsTranslationManager
7
- class ImporterTest < Minitest::Test
8
- test 'should create a new locale file for a filled in translation csv file' do
9
- given_csv(:fr,
10
- [:key, :source, :translation],
11
- ["world_location.type.country", "Country", "Pays"],
12
- ["world_location.country", "Germany", "Allemange"],
13
- ["other.nested.key", "original", "translated"]
14
- )
15
-
16
- Importer.new(:fr, csv_path(:fr), import_directory).import
17
-
18
- yaml_translation_data = YAML.load_file(File.join(import_directory, "fr.yml"))
19
- expected = {"fr" => {
20
- "world_location" => {
21
- "country" => "Allemange",
22
- "type" => {
23
- "country" => "Pays"
24
- }
25
- },
26
- "other" => {
27
- "nested" => {
28
- "key" => "translated"
29
- }
30
- }
31
- }}
32
- assert_equal expected, yaml_translation_data
33
- end
34
-
35
- test 'imports arrays from CSV as arrays' do
36
- given_csv(:fr,
37
- [:key, :source, :translation],
38
- ["fruit", ["Apples", "Bananas", "Pears"], ["Pommes", "Bananes", "Poires"]]
39
- )
40
-
41
- Importer.new(:fr, csv_path(:fr), import_directory).import
42
-
43
- yaml_translation_data = YAML.load_file(File.join(import_directory, "fr.yml"))
44
- expected = {"fr" => {
45
- "fruit" => ["Pommes", "Bananes", "Poires"]
46
- }}
47
- assert_equal expected, yaml_translation_data
48
- end
49
-
50
- test 'interprets string "nil" as nil' do
51
- given_csv(:fr,
52
- [:key, :source, :translation],
53
- ["things", ["one", nil, "two"], ["une", nil, "deux"]]
54
- )
55
-
56
- Importer.new(:fr, csv_path(:fr), import_directory).import
57
-
58
- yaml_translation_data = YAML.load_file(File.join(import_directory, "fr.yml"))
59
- expected = {"fr" => {
60
- "things" => ["une", nil, "deux"]
61
- }}
62
- assert_equal expected, yaml_translation_data
63
- end
64
-
65
- test 'interprets string ":thing" as symbol' do
66
- given_csv(:fr,
67
- [:key, :source, :translation],
68
- ["sentiment", ":whatever", ":bof"]
69
- )
70
-
71
- Importer.new(:fr, csv_path(:fr), import_directory).import
72
-
73
- yaml_translation_data = YAML.load_file(File.join(import_directory, "fr.yml"))
74
- expected = {"fr" => {
75
- "sentiment" => :bof
76
- }}
77
- assert_equal expected, yaml_translation_data
78
- end
79
-
80
- test 'interprets integer strings as integers' do
81
- given_csv(:fr,
82
- [:key, :source, :translation],
83
- ["price", "123", "123"]
84
- )
85
-
86
- Importer.new(:fr, csv_path(:fr), import_directory).import
87
-
88
- yaml_translation_data = YAML.load_file(File.join(import_directory, "fr.yml"))
89
- expected = {"fr" => {
90
- "price" => 123
91
- }}
92
- assert_equal expected, yaml_translation_data
93
- end
94
-
95
- test 'interprets boolean values as booleans, not strings' do
96
- given_csv(:fr,
97
- [:key, :source, :translation],
98
- ["key1", "is true", "true"],
99
- ["key2", "is false", "false"]
100
- )
101
-
102
- Importer.new(:fr, csv_path(:fr), import_directory).import
103
-
104
- yaml_translation_data = YAML.load_file(File.join(import_directory, "fr.yml"))
105
- expected = {"fr" => {
106
- "key1" => true,
107
- "key2" => false
108
- }}
109
- assert_equal expected, yaml_translation_data
110
- end
111
-
112
- private
113
-
114
- def csv_path(locale)
115
- File.join(import_directory, "#{locale}.csv")
116
- end
117
-
118
- def given_csv(locale, header_row, *rows)
119
- csv = CSV.generate do |csv|
120
- csv << CSV::Row.new(["key", "source", "translation"], ["key", "source", "translation"], true)
121
- rows.each do |row|
122
- csv << CSV::Row.new(["key", "source", "translation"], row)
123
- end
124
- end
125
- File.open(csv_path(locale), "w") { |f| f.write csv.to_s }
126
- end
127
-
128
- def import_directory
129
- @import_directory ||= Dir.mktmpdir
130
- end
131
- end
132
- end
@@ -1,251 +0,0 @@
1
- require "test_helper"
2
-
3
- require "rails_translation_manager/stealer"
4
- require "fileutils"
5
- require "tmpdir"
6
- require "csv"
7
- require "i18n"
8
-
9
- module RailsTranslationManager
10
- class StealerTest < Minitest::Test
11
-
12
- test "converts subtree of items to the same depth" do
13
-
14
- original = {
15
- "fr" => {
16
- "document" => {
17
- "type" => {
18
- "type1" => 'premier genre',
19
- "type2" => 'deuxième genre',
20
- "type3" => 'troisième genre'
21
- }
22
- }
23
- }
24
- }
25
-
26
- conversion_mapping = {
27
- "document.type" => "content_item.format",
28
- }
29
-
30
- expected = {
31
- "fr" => {
32
- "content_item" => {
33
- "format" => {
34
- "type1" => 'premier genre',
35
- "type2" => 'deuxième genre',
36
- "type3" => 'troisième genre'
37
- }
38
- }
39
- }
40
- }
41
- stealer_test(original, conversion_mapping, expected)
42
- end
43
-
44
- test "converts a subtree of items to a different depth" do
45
- original = {
46
- "fr" => {
47
- "document" => {
48
- "published" => 'publiée',
49
- }
50
- }
51
- }
52
- conversion_mapping = {
53
- "document.published" => "content_item.metadata.published"
54
- }
55
-
56
- expected = {
57
- "fr" => {
58
- "content_item" => {
59
- "metadata" => {
60
- "published" => 'publiée'
61
- }
62
- }
63
- }
64
- }
65
-
66
- stealer_test(original, conversion_mapping, expected)
67
- end
68
-
69
- test "combines multiple mappings" do
70
- original = {
71
- "fr" => {
72
- "document" => {
73
- "type" => {
74
- "type1" => 'premier genre',
75
- },
76
- "published" => 'publiée',
77
- }
78
- }
79
- }
80
-
81
- conversion_mapping = {
82
- "document.type" => "content_item.format",
83
- "document.published" => "content_item.metadata.published"
84
- }
85
- expected = {
86
- "fr" => {
87
- "content_item" => {
88
- "format" => {
89
- "type1" => 'premier genre',
90
- },
91
- "metadata" => {
92
- "published" => 'publiée',
93
- }
94
- }
95
- }
96
- }
97
- stealer_test(original, conversion_mapping, expected)
98
- end
99
-
100
- test "does not copy over keys with no mapping" do
101
- original = {
102
- "fr" => {
103
- "document" => {
104
- "published" => 'publiée',
105
- "do_not_want" => 'non voulu'
106
- }
107
- }
108
- }
109
- conversion_mapping = {
110
- "document.published" => "content_item.metadata.published"
111
- }
112
-
113
- expected = {
114
- "fr" => {
115
- "content_item" => {
116
- "metadata" => {
117
- "published" => 'publiée'
118
- }
119
- }
120
- }
121
- }
122
-
123
- stealer_test(original, conversion_mapping, expected)
124
- end
125
-
126
- test "overrides existing translations present in mapping" do
127
- original = {
128
- "fr" => {
129
- "document" => {
130
- "published" => 'publiée',
131
- "updated" => 'mise au jour',
132
- }
133
- }
134
- }
135
-
136
- conversion_mapping = {
137
- "document.published" => "content_item.metadata.published",
138
- "document.updated" => "content_item.metadata.updated"
139
- }
140
-
141
- existing = {
142
- "fr" => {
143
- "content_item" => {
144
- "metadata" => {
145
- "updated" => 'mauvaise traduction'
146
- }
147
- }
148
- }
149
- }
150
-
151
- expected = {
152
- "fr" => {
153
- "content_item" => {
154
- "metadata" => {
155
- "published" => 'publiée',
156
- "updated" => 'mise au jour',
157
- }
158
- }
159
- }
160
- }
161
- stealer_test(original, conversion_mapping, expected, existing)
162
- end
163
-
164
- test "does not override existing translations not in mapping" do
165
- original = {
166
- "fr" => {
167
- "document" => {
168
- "published" => 'publiée',
169
- }
170
- }
171
- }
172
-
173
- conversion_mapping = {
174
- "document.published" => "content_item.metadata.published"
175
- }
176
-
177
- existing = {
178
- "fr" => {
179
- "content_item" => {
180
- "metadata" => {
181
- "updated" => 'mise au jour',
182
- }
183
- }
184
- }
185
- }
186
-
187
- expected = {
188
- "fr" => {
189
- "content_item" => {
190
- "metadata" => {
191
- "published" => 'publiée',
192
- "updated" => 'mise au jour',
193
- }
194
- }
195
- }
196
- }
197
- stealer_test(original, conversion_mapping, expected, existing)
198
- end
199
-
200
- private
201
-
202
- def stealer_test(original, mapping, expected, existing=nil)
203
- write_source_data(original)
204
- write_converter_data(mapping)
205
-
206
- if existing.present?
207
- File.open(locale_file, 'w') do |f|
208
- f.puts(existing.to_yaml)
209
- end
210
- end
211
-
212
- stealer = RailsTranslationManager::Stealer.new("fr", source_dir, converter_path, locales_dir)
213
- stealer.steal_locale
214
-
215
- assert_equal expected, YAML.load_file(locale_file)
216
- end
217
-
218
- def source_dir
219
- @source_dir ||= Dir.mktmpdir
220
- end
221
-
222
- def source_locale_path
223
- File.join(source_dir, 'config/locales')
224
- end
225
-
226
- def write_source_data(data)
227
- FileUtils.mkdir_p(source_locale_path)
228
- File.open(File.join(source_locale_path, 'fr.yml'), 'w') do |f|
229
- f.puts(data.to_yaml)
230
- end
231
- end
232
-
233
- def write_converter_data(data)
234
- File.open(converter_path, 'w') do |f|
235
- f.puts(data.to_yaml)
236
- end
237
- end
238
-
239
- def converter_path
240
- @converter_path ||= Tempfile.new('fr').path
241
- end
242
-
243
- def locales_dir
244
- @locales_dir ||= Dir.mktmpdir
245
- end
246
-
247
- def locale_file
248
- File.join(locales_dir, 'fr.yml')
249
- end
250
- end
251
- end
@@ -1,51 +0,0 @@
1
- # encoding: utf-8
2
- require 'test_helper'
3
- require 'rails_translation_manager/validator'
4
- require 'tmpdir'
5
- require 'fileutils'
6
-
7
- module RailsTranslationManager
8
- class ValidatorTest < Minitest::Test
9
- def setup
10
- @translation_path = Dir.mktmpdir
11
- @translation_validator = Validator.new(@translation_path)
12
- end
13
-
14
- def teardown
15
- FileUtils.remove_entry_secure(@translation_path)
16
- end
17
-
18
- def create_translation_file(locale, content)
19
- File.open(File.join(@translation_path, "#{locale}.yml"), "w") do |f|
20
- f.write(content.lstrip)
21
- end
22
- end
23
-
24
- test "can create a flattened list of substitutions" do
25
- translation_file = YAML.load(%q{
26
- en:
27
- view: View '%{title}'
28
- test: foo
29
- })
30
- expected = [Validator::TranslationEntry.new(%w{en view}, "View '%{title}'")]
31
- assert_equal expected, @translation_validator.substitutions_in(translation_file)
32
- end
33
-
34
- test "detects extra substitution keys" do
35
- create_translation_file("en", %q{
36
- en:
37
- document:
38
- view: View '%{title}'
39
- })
40
- create_translation_file("sr", %q{
41
- sr:
42
- document:
43
- view: Pročitajte '%{naslov}'
44
- })
45
- errors = Validator.new(@translation_path).check!
46
-
47
- expected = %q{Key "sr.document.view": Extra substitutions: ["naslov"]. Missing substitutions: ["title"].}
48
- assert_equal [expected], errors.map(&:to_s)
49
- end
50
- end
51
- end