rails_translation_manager 0.0.1 → 0.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bcf654f074b115a7c80d173e821333d2b8b35b01
4
- data.tar.gz: 84cea8e22ca03313c47e7432be605cee30905391
3
+ metadata.gz: b5174ef0679b5689038dba575d7739d110109836
4
+ data.tar.gz: de386962792fc2d729e98183b7e4c962d41798c1
5
5
  SHA512:
6
- metadata.gz: 6823237f243a4127c4c14ece436ec69212c1e481a1d11d8329649cfbcdc61177bf73f0097c1978fed353c863c83949f9eee62f616c16086f28757ce6645b5f0b
7
- data.tar.gz: 2d8bc1c02272590a00a8bcbec3d002cec989f27c69e5025e65729ebf56c198089d0f29c8f7b87aaab5434642b28f2f11037a9596babdb1e096dd9ff8bda1a850
6
+ metadata.gz: 3e07bb3ed5ec4b2a4f73672f626d0b579240a63115e7ad39345e00b68912f0ecafadbc5666e28ed365aceef30011a24d6821f805b512e1d8c3a3685c38b5ea7c
7
+ data.tar.gz: 96aab0397474451f60f6de06dd2cff484851b493e7f6d5ebd4714aafab99546ebc1f34b8795d70c3282da03cf79a02f2721064ac696fd0c182dba5a2c3591482
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## 0.0.2
2
+
3
+ Added `steal` rake tasks to copy translations from another app.
4
+
5
+ ## 0.0.1
6
+
7
+ Initial release.
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
  The MIT License (MIT)
2
- Copyright (C) 2015 HM Government (Government Digital Service)
2
+ Copyright (C) 2015 Crown Copyright (Government Digital Service)
3
3
 
4
4
  MIT License
5
5
 
data/README.md CHANGED
@@ -124,6 +124,48 @@ $ rake translation:validate
124
124
  Success! No unexpected interpolation keys found.
125
125
  ```
126
126
 
127
+ ### Stealing translations from another app
128
+
129
+ A third feature is the ability to "steal" one or more locales from an existing
130
+ application. This functionality works by providing a mapping file, which defines
131
+ how the translation keys in the the source app's files map to those in the app
132
+ the gem is installed in.
133
+
134
+ For example, given a locale file like this in the app to "steal" from:
135
+
136
+ ```yaml
137
+ es:
138
+ document:
139
+ type:
140
+ case_study: Caso de estudio
141
+ consultation: Consulta
142
+ ```
143
+
144
+ and a mapping file like this:
145
+
146
+ ```yaml
147
+ document.type: content_item.format
148
+ ```
149
+
150
+ running `rake translation:steal[es,../other_app,mapping_file_path.yml]` will
151
+ result in the following locale file being created:
152
+
153
+ ```yaml
154
+ es:
155
+ content_item:
156
+ format:
157
+ case_study: Caso de estudio
158
+ consultation: Consulta
159
+ ```
160
+
161
+ The mapping file can live anywhere, as long as the full path (including filename)
162
+ is given in the rake task invocation.
163
+
164
+ The process will preserve data already in the output file if it is not
165
+ referenced in the mapping, but will always override data belonging to keys
166
+ that are in the mapping.
167
+
168
+
127
169
  ### Rake command reference
128
170
 
129
171
  #### Export a specific locale to CSV
@@ -150,6 +192,8 @@ rake translation:import[locale,path]
150
192
  rake translation:import:all[directory]
151
193
  ```
152
194
 
195
+ ####
196
+
153
197
  #### Regenerate all locales from the EN locale - run this after adding keys
154
198
 
155
199
  ```
@@ -162,6 +206,18 @@ rake translation:regenerate[directory]
162
206
  rake translation:validate
163
207
  ```
164
208
 
209
+ #### Steal a specific locale file from another app
210
+
211
+ ```
212
+ rake translation:steal[locale,source_app_path,mapping_file_path]
213
+ ```
214
+
215
+ #### Steal all locale files from another app
216
+
217
+ ```
218
+ rake translation:steal:all[source_app_path,mapping_file_path]
219
+ ```
220
+
165
221
  ### Running the test suite
166
222
 
167
223
  To run the test suite just run `bundle exec rake` from within the
data/Rakefile CHANGED
@@ -9,4 +9,10 @@ Rake::TestTask.new("test") do |t|
9
9
  t.verbose = true
10
10
  end
11
11
 
12
+ require "gem_publisher"
13
+ task :publish_gem do |t|
14
+ gem = GemPublisher.publish_if_updated("rails_translation_manager.gemspec", :rubygems)
15
+ puts "Published #{gem}" if gem
16
+ end
17
+
12
18
  task :default => :test
data/jenkins.sh ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/bash -x
2
+ set -e
3
+ rm -f Gemfile.lock
4
+ bundle install --path "${HOME}/bundles/${JOB_NAME}"
5
+ export GOVUK_APP_DOMAIN=dev.gov.uk
6
+ bundle exec rake test
7
+ if [[ -n "$PUBLISH_GEM" ]]; then
8
+ bundle exec rake publish_gem --trace
9
+ fi
@@ -5,4 +5,5 @@ require "rails-i18n"
5
5
  module RailsTranslationManager
6
6
  autoload :Exporter, "rails_translation_manager/exporter"
7
7
  autoload :Importer, "rails_translation_manager/importer"
8
+ autoload :Stealer, "rails_translation_manager/stealer"
8
9
  end
@@ -1,7 +1,10 @@
1
1
  require "yaml"
2
2
  require "csv"
3
+ require_relative "yaml_writer"
3
4
 
4
5
  class RailsTranslationManager::Importer
6
+ include YAMLWriter
7
+
5
8
  def initialize(locale, csv_path, import_directory)
6
9
  @csv_path = csv_path
7
10
  @locale = locale
@@ -25,12 +28,7 @@ class RailsTranslationManager::Importer
25
28
  end
26
29
  end
27
30
 
28
- File.open(import_yml_path, "w") do |f|
29
- yaml = {@locale.to_s => data}.to_yaml(separator: "")
30
- yaml_without_header = yaml.split("\n").map { |l| l.gsub(/\s+$/, '') }[1..-1].join("\n")
31
- f.write(yaml_without_header)
32
- f.puts
33
- end
31
+ write_yaml(import_yml_path, {@locale.to_s => data})
34
32
  end
35
33
 
36
34
  private
@@ -0,0 +1,85 @@
1
+ require "yaml"
2
+ require "i18n"
3
+ require_relative "yaml_writer"
4
+
5
+ class RailsTranslationManager::Stealer
6
+ include YAMLWriter
7
+
8
+ # locale is the locale name as a string.
9
+ # source_app_path is the path to the root of the app to steal from.
10
+ # mapping_file_path is the path to a YAML file mapping translation keys in
11
+ # the source app to those in the target app. For example:
12
+ # document.type: content_item.format
13
+ # document.published: content_item.metadata.published
14
+ # which will import everything under "document.type" and "document.published"
15
+ # in the source app, and write it to "content_item.format" and
16
+ # "content_item.metadata.published" in the target app.
17
+ # locales_path is the path to the locale files to output, which is usually
18
+ # Rails.root.join('config/locales').
19
+ # The process will preserve data already in the output file if it is not
20
+ # referenced in the mapping, but will always override data belonging to keys
21
+ # that are in the mapping.
22
+ def initialize(locale, source_app_path, mapping_file_path, locales_path)
23
+ @locale = locale
24
+ @source_app_path = source_app_path
25
+ @mapping_file_path = mapping_file_path
26
+ @locales_path = locales_path
27
+ end
28
+
29
+ def steal_locale
30
+ target_data = convert_locale(get_target_data)
31
+ write_yaml(target_locale_path, target_data)
32
+ end
33
+
34
+ def convert_locale(target_data)
35
+ mapping_data.each do |source, target|
36
+ data = source_data[@locale]
37
+ source.split('.').each { |key| data = data.fetch(key, {}) }
38
+ set_recursive(target_data[@locale], target.split("."), data)
39
+ end
40
+ target_data
41
+ end
42
+
43
+ private
44
+
45
+ def set_recursive(hash, keys, data)
46
+ if keys.empty?
47
+ data
48
+ else
49
+ key = keys.shift
50
+ hash.tap do |h|
51
+ h.merge!({ key => set_recursive(hash.fetch(key, {}), keys, data)})
52
+ end
53
+ end
54
+ end
55
+
56
+ def source_locale_path
57
+ File.join(@source_app_path, 'config', 'locales', "#{@locale}.yml")
58
+ end
59
+
60
+ def source_data
61
+ @source_data ||= YAML.load_file(source_locale_path)
62
+ end
63
+
64
+ def target_locale_path
65
+ File.join(@locales_path, "#{@locale}.yml")
66
+ end
67
+
68
+ def default_target_data
69
+ { @locale => {} }
70
+ end
71
+
72
+ def get_target_data
73
+ if File.exist?(target_locale_path)
74
+ YAML.load_file(target_locale_path) || default_target_data
75
+ else
76
+ default_target_data
77
+ end
78
+ end
79
+
80
+ def mapping_data
81
+ @mapping_data ||= YAML.load_file(@mapping_file_path)
82
+ end
83
+
84
+ end
85
+
@@ -1,3 +1,3 @@
1
1
  module RailsTranslationManager
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,17 @@
1
+ require 'yaml'
2
+
3
+ module YAMLWriter
4
+
5
+ # `to_yaml` outputs an initial '---\n', which is supposed to be a document
6
+ # separator. We don't want this in the written locale files, so we serialize
7
+ # to a string, remove the header and any trailing whitehspace, and write to
8
+ # the file.
9
+ def write_yaml(filepath, data)
10
+ File.open(filepath, "w") do |f|
11
+ yaml = data.to_yaml(separator: "")
12
+ yaml_without_header = yaml.split("\n").map { |l| l.gsub(/\s+$/, '') }[1..-1].join("\n")
13
+ f.write(yaml_without_header)
14
+ f.puts
15
+ end
16
+ end
17
+ end
@@ -67,4 +67,21 @@ namespace :translation do
67
67
  puts "Success! No unexpected interpolation keys found."
68
68
  end
69
69
  end
70
+
71
+ desc "Import and convert a locale file from another app."
72
+ task :steal, [:locale, :source_app_path, :mapping_file_path] do |t, args|
73
+ stealer = RailsTranslationManager::Stealer.new(args[:locale], args[:source_app_path], args[:mapping_file_path], Rails.root.join('config', 'locales'))
74
+ stealer.steal_locale
75
+ end
76
+
77
+ namespace :steal do
78
+ desc "Import and convert all locale files from another app."
79
+ task :all, [:source_app_path, :mapping_file_path] => [:environment] do |t, args|
80
+ I18n.available_locales.reject { |l| l == :en }.each do |locale|
81
+ stealer = RailsTranslationManager::Stealer.new(locale.to_s, args[:source_app_path], args[:mapping_file_path], Rails.root.join('config', 'locales'))
82
+ stealer.steal_locale
83
+ end
84
+ end
85
+ end
86
+
70
87
  end
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency "activesupport"
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency 'gem_publisher', '~> 1.1.1'
25
26
  spec.add_development_dependency "rake", "~> 10.0"
26
27
  spec.add_development_dependency "minitest"
27
28
  end
@@ -32,40 +32,6 @@ module RailsTranslationManager
32
32
  assert_equal expected, yaml_translation_data
33
33
  end
34
34
 
35
- test 'outputs YAML without the header --- line for consistency with convention' do
36
- given_csv(:fr,
37
- [:key, :source, :translation],
38
- ["key", "value", "le value"],
39
- )
40
-
41
- Importer.new(:fr, csv_path(:fr), import_directory).import
42
-
43
- assert_equal "fr:", File.readlines(File.join(import_directory, "fr.yml")).first.strip
44
- end
45
-
46
- test 'outputs a newline at the end of the YAML for consistency with code editors' do
47
- given_csv(:fr,
48
- [:key, :source, :translation],
49
- ["key", "value", "le value"],
50
- )
51
-
52
- Importer.new(:fr, csv_path(:fr), import_directory).import
53
-
54
- assert_match /\n$/, File.readlines(File.join(import_directory, "fr.yml")).last
55
- end
56
-
57
- test 'strips whitespace from the end of lines for consistency with code editors' do
58
- given_csv(:fr,
59
- [:key, :source, :translation],
60
- ["key", "value", nil],
61
- )
62
-
63
- Importer.new(:fr, csv_path(:fr), import_directory).import
64
-
65
- lines = File.readlines(File.join(import_directory, "fr.yml"))
66
- refute lines.any? { |line| line =~ /\s\n$/ }
67
- end
68
-
69
35
  test 'imports arrays from CSV as arrays' do
70
36
  given_csv(:fr,
71
37
  [:key, :source, :translation],
@@ -0,0 +1,251 @@
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
@@ -0,0 +1,58 @@
1
+ module RailsTranslationManager
2
+ class DummyWriter
3
+ include YAMLWriter
4
+ end
5
+
6
+ class WriterTest < Minitest::Test
7
+
8
+ def setup
9
+ @output_file = Tempfile.new('fr')
10
+ end
11
+
12
+ def teardown
13
+ @output_file.close
14
+ @output_file.unlink
15
+ end
16
+
17
+ test 'outputs YAML without the header --- line for consistency with convention' do
18
+ data = {"fr" => {
19
+ key1: [:source, :translation],
20
+ "key2" => ["value", "le value"],
21
+ }}
22
+
23
+ DummyWriter.new.write_yaml(output_file, data)
24
+
25
+ assert_equal "fr:", File.readlines(output_file).first.strip
26
+ end
27
+
28
+ test 'outputs a newline at the end of the YAML for consistency with code editors' do
29
+ data = {"fr" => {
30
+ key1: [:source, :translation],
31
+ "key2" => ["value", "le value"],
32
+ }}
33
+
34
+ DummyWriter.new.write_yaml(output_file, data)
35
+
36
+ assert_match /\n$/, File.readlines(output_file).last
37
+ end
38
+
39
+ test 'strips whitespace from the end of lines for consistency with code editors' do
40
+ data = {fr: {
41
+ key1: [:source, :translation],
42
+ "key2" => ["value", nil],
43
+ }}
44
+
45
+ DummyWriter.new.write_yaml(output_file, data)
46
+
47
+ lines = File.readlines(output_file)
48
+ refute lines.any? { |line| line =~ /\s\n$/ }
49
+ end
50
+
51
+ private
52
+
53
+ def output_file
54
+ @output_file.path
55
+ end
56
+ end
57
+ end
58
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_translation_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edd Sowden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-09 00:00:00.000000000 Z
11
+ date: 2015-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails-i18n
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gem_publisher
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.1
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -90,22 +104,28 @@ files:
90
104
  - ".gitignore"
91
105
  - ".ruby-version"
92
106
  - ".travis.yml"
107
+ - CHANGELOG.md
93
108
  - CONTRIBUTING.md
94
109
  - Gemfile
95
110
  - LICENSE.txt
96
111
  - README.md
97
112
  - Rakefile
113
+ - jenkins.sh
98
114
  - lib/rails_translation_manager.rb
99
115
  - lib/rails_translation_manager/exporter.rb
100
116
  - lib/rails_translation_manager/importer.rb
101
117
  - lib/rails_translation_manager/railtie.rb
118
+ - lib/rails_translation_manager/stealer.rb
102
119
  - lib/rails_translation_manager/validator.rb
103
120
  - lib/rails_translation_manager/version.rb
121
+ - lib/rails_translation_manager/yaml_writer.rb
104
122
  - lib/tasks/translation.rake
105
123
  - rails_translation_manager.gemspec
106
124
  - test/rails_translation_manager/exporter_test.rb
107
125
  - test/rails_translation_manager/importer_test.rb
126
+ - test/rails_translation_manager/stealer_test.rb
108
127
  - test/rails_translation_manager/validator_test.rb
128
+ - test/rails_translation_manager/yaml_writer_test.rb
109
129
  - test/test_helper.rb
110
130
  homepage: ''
111
131
  licenses:
@@ -134,5 +154,7 @@ summary: Tasks to manage translation files
134
154
  test_files:
135
155
  - test/rails_translation_manager/exporter_test.rb
136
156
  - test/rails_translation_manager/importer_test.rb
157
+ - test/rails_translation_manager/stealer_test.rb
137
158
  - test/rails_translation_manager/validator_test.rb
159
+ - test/rails_translation_manager/yaml_writer_test.rb
138
160
  - test/test_helper.rb