rails_translation_manager 0.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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