i18n_generators 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/History.txt +6 -0
  2. data/README.rdoc +8 -11
  3. data/Rakefile +8 -0
  4. data/i18n_generators.gemspec +4 -0
  5. data/lib/generators/i18n/i18n_generator.rb +2 -2
  6. data/lib/generators/i18n_translation/i18n_translation_generator.rb +69 -41
  7. data/lib/generators/i18n_translation/lib/yaml.rb +4 -4
  8. data/lib/i18n_generators/version.rb +1 -1
  9. data/spec/i18n_locale_command_spec.rb +34 -26
  10. data/spec/i18n_translation_command_spec.rb +6 -10
  11. data/spec/spec_helper.rb +6 -1
  12. data/spec/translator_spec.rb +11 -18
  13. data/spec/yaml_spec.rb +5 -4
  14. metadata +49 -35
  15. data/generators/i18n/USAGE +0 -11
  16. data/generators/i18n/i18n_generator.rb +0 -88
  17. data/generators/i18n/lib/yaml.rb +0 -187
  18. data/generators/i18n/templates/base.yml +0 -0
  19. data/generators/i18n/templates/i18n_config.rb +0 -4
  20. data/generators/i18n/templates/translation.yml +0 -1
  21. data/generators/i18n_locale/USAGE +0 -10
  22. data/generators/i18n_locale/i18n_locale_command.rb +0 -141
  23. data/generators/i18n_locale/i18n_locale_generator.rb +0 -8
  24. data/generators/i18n_locale/lib/cldr.rb +0 -138
  25. data/generators/i18n_scaffold/i18n_scaffold_generator.rb +0 -2
  26. data/generators/i18n_scaffold/templates/controller.rb +0 -85
  27. data/generators/i18n_scaffold/templates/functional_test.rb +0 -45
  28. data/generators/i18n_scaffold/templates/helper.rb +0 -2
  29. data/generators/i18n_scaffold/templates/helper_test.rb +0 -4
  30. data/generators/i18n_scaffold/templates/layout.html.erb +0 -17
  31. data/generators/i18n_scaffold/templates/style.css +0 -54
  32. data/generators/i18n_scaffold/templates/view_edit.html.erb +0 -18
  33. data/generators/i18n_scaffold/templates/view_index.html.erb +0 -24
  34. data/generators/i18n_scaffold/templates/view_new.html.erb +0 -17
  35. data/generators/i18n_scaffold/templates/view_show.html.erb +0 -10
  36. data/generators/i18n_translation/USAGE +0 -8
  37. data/generators/i18n_translation/i18n_translation_command.rb +0 -124
  38. data/generators/i18n_translation/i18n_translation_generator.rb +0 -8
  39. data/generators/i18n_translation/lib/erb_executer.rb +0 -30
  40. data/generators/i18n_translation/lib/recording_backend.rb +0 -15
  41. data/generators/i18n_translation/lib/through_ryoku.rb +0 -7
  42. data/generators/i18n_translation/lib/translator.rb +0 -27
  43. data/spec/cldr_spec.rb +0 -54
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ == 1.2.0
2
+
3
+ * enhancements:
4
+ * Drop Rails 2 support
5
+ * Put alias to model name for non-collection reflection names (see: https://twitter.com/#!/znz/status/179109337581625344) (thanks to znz-san!)
6
+
1
7
  == 1.1.0
2
8
 
3
9
  * enhancements:
data/README.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = I18n generators
2
2
 
3
- This gem plugin generates a set of locale files for Rails i18n feature. Supports Rails 3.1, 3.0.x, 2.3.x and 2.2.x.
3
+ This gem plugin generates a set of locale files for Rails i18n feature. Supports Rails 4.0, 3.2.x, 3.1.x, 3.0.x, 2.3.x and 2.2.x.
4
4
 
5
5
  * http://github.com/amatsuda/i18n_generators
6
6
  * http://rubygems.org/gems/i18n_generators
@@ -44,23 +44,20 @@ Executes 1 and 2 at once.
44
44
 
45
45
  == REQUIREMENTS:
46
46
 
47
- * Ruby (>= 1.8.7)
48
- * Ruby on Rails (3.1 or 3.0 or 2.3 or 2.2)
47
+ * Ruby 1.8.7, 1.9, 2.0
48
+ * Ruby on Rails 4.0, 3.2, 3.1, 3.0
49
+ * Ruby on Rails 2.3, 2.2 (supported by i18n_generators < 1.2)
49
50
 
50
51
 
51
52
  == INSTALL:
52
53
 
53
- * As a gem
54
-
55
- % gem install i18n_generators
56
-
57
- * With Bundler
54
+ * Rails 3 (with Bundler)
58
55
 
59
56
  Add 'i18n_generators' to your Gemfile, then `bundle`. Restricting the group to :development would be a good idea, since the generator would probably be used only in development mode.
60
57
 
61
- * As a Rails plugin
58
+ * Rails 2
62
59
 
63
- % rails plugin install git://github.com/amatsuda/i18n_generators.git
60
+ Use 'i18n_generators' version '< 1.2'.
64
61
 
65
62
 
66
- Copyright (c) 2008 - 2011 Akira Matsuda, released under the MIT license
63
+ Copyright (c) 2008 Akira Matsuda, released under the MIT license
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => :spec
@@ -23,4 +23,8 @@ Gem::Specification.new do |s|
23
23
  s.licenses = ['MIT']
24
24
 
25
25
  s.add_runtime_dependency 'mechanize'
26
+ s.add_runtime_dependency 'rails', '>= 3.0.0'
27
+ s.add_development_dependency 'rails'
28
+ s.add_development_dependency 'rspec'
29
+ s.add_development_dependency 'rake'
26
30
  end
@@ -1,5 +1,5 @@
1
- require File.join(File.dirname(__FILE__), '../i18n_translation/i18n_translation_generator')
2
- require File.join(File.dirname(__FILE__), '../i18n_locale/i18n_locale_generator')
1
+ require 'generators/i18n_translation/i18n_translation_generator'
2
+ require 'generators/i18n_locale/i18n_locale_generator'
3
3
 
4
4
  class I18nGenerator < Rails::Generators::NamedBase
5
5
  def initialize(args, *options)
@@ -1,5 +1,5 @@
1
- require File.join(File.dirname(__FILE__), 'lib/yaml')
2
- require File.join(File.dirname(__FILE__), 'lib/translator')
1
+ require 'generators/i18n_translation/lib/yaml'
2
+ require 'generators/i18n_translation/lib/translator'
3
3
 
4
4
  class I18nTranslationGenerator < Rails::Generators::NamedBase
5
5
  # option: include_timestamps
@@ -12,12 +12,20 @@ class I18nTranslationGenerator < Rails::Generators::NamedBase
12
12
  I18n.locale = locale_name
13
13
  Rails.application.eager_load!
14
14
 
15
- keys = aggregate_keys
16
- translations = translate_all(keys)
15
+ # activerecord:models comes first
16
+ model_names_translations = order_hash translate_all(model_names_keys)
17
+ # activerecord:models:attributes comes next
18
+ attribute_names_translations = ActiveSupport::OrderedHash.new
19
+ attribute_names_translations.merge! translate_all(content_column_names_keys)
20
+ attribute_names_translations.merge! translate_all(collection_reflection_names_keys)
21
+ # refer to already translated model names
22
+ attribute_names_translations.merge! singular_reflection_names_references
23
+ # merge them all
24
+ translations = model_names_translations.deep_merge order_hash(attribute_names_translations)
17
25
 
18
26
  yaml = I27r::YamlDocument.load_yml_file "config/locales/translation_#{locale_name}.yml"
19
27
  each_value [], translations do |parents, value|
20
- if value.is_a? String
28
+ if value.is_a?(String) || value.is_a?(Symbol)
21
29
  yaml[[locale_name.to_s] + parents] = value
22
30
  else
23
31
  value.each do |key, val|
@@ -32,8 +40,8 @@ class I18nTranslationGenerator < Rails::Generators::NamedBase
32
40
  end
33
41
 
34
42
  private
35
- def aggregate_keys
36
- models = ActiveRecord::Base.descendants.map do |m|
43
+ def models
44
+ @models ||= ActiveRecord::Base.descendants.map do |m|
37
45
  begin
38
46
  m if m.table_exists? && m.respond_to?(:content_columns)
39
47
  rescue => e
@@ -41,48 +49,54 @@ class I18nTranslationGenerator < Rails::Generators::NamedBase
41
49
  next
42
50
  end
43
51
  end.compact
52
+ end
53
+
54
+ def model_names_keys
55
+ models.map {|m| "activerecord.models.#{m.model_name.underscore}"}
56
+ end
44
57
 
45
- translation_keys = []
46
- translation_keys += models.map {|m| "activerecord.models.#{m.model_name.underscore}"}
47
- models.each do |model|
48
- cols = model.content_columns + model.reflect_on_all_associations
49
- cols.delete_if {|c| %w[created_at updated_at].include? c.name} unless include_timestamps?
50
- translation_keys += cols.map {|c| "activerecord.attributes.#{model.model_name.underscore}.#{c.name}"}
58
+ def content_column_names_keys
59
+ models.map {|m|
60
+ cols = m.content_columns.map {|c| c.name}
61
+ cols.delete_if {|c| %w[created_at updated_at].include? c} unless include_timestamps?
62
+ cols.map {|c| "activerecord.attributes.#{m.model_name.underscore}.#{c}"}
63
+ }.flatten
64
+ end
65
+
66
+ def singular_reflection_names_references
67
+ ret = {}
68
+ models.each do |m|
69
+ m.reflect_on_all_associations.select {|c| !c.collection?}.each do |c|
70
+ ret["activerecord.attributes.#{m.model_name.underscore}.#{c.name}"] = "activerecord.models.#{c.name}".to_sym
71
+ end
51
72
  end
52
- translation_keys
73
+ ret
74
+ end
75
+
76
+ def collection_reflection_names_keys
77
+ models.map {|m|
78
+ m.reflect_on_all_associations.select {|c| c.collection?}.map {|c| "activerecord.attributes.#{m.model_name.underscore}.#{c.name}"}
79
+ }.flatten
80
+ end
81
+
82
+ def translator
83
+ @translator ||= I27r::Translator.new locale_name.sub(/\-.*/, '')
53
84
  end
54
85
 
55
86
  # receives an array of keys and returns :key => :translation hash
56
87
  def translate_all(keys)
57
- translator = I27r::Translator.new locale_name.sub(/\-.*/, '')
58
-
59
- ActiveSupport::OrderedHash.new.tap do |oh|
60
- # fix the order first(for multi thread translating)
61
- keys.each do |key|
62
- if key.to_s.include? '.'
63
- key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
64
- key_prefix.inject(oh) {|h, k| h[k] ||= ActiveSupport::OrderedHash.new}[key_suffix] = nil
65
- else
66
- oh[key] = nil
67
- end
68
- end
69
- threads = []
70
- keys.each do |key|
71
- threads << Thread.new do
72
- Rails.logger.debug "translating #{key} ..."
73
- Thread.pass
74
- if key.to_s.include? '.'
75
- key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
76
- existing_translation = I18n.backend.send(:lookup, locale_name, key_suffix, key_prefix)
77
- key_prefix.inject(oh) {|h, k| h[k]}[key_suffix] = existing_translation ? existing_translation : translator.translate(key_suffix)
78
- else
79
- existing_translation = I18n.backend.send(:lookup, locale_name, key)
80
- oh[key] = existing_translation ? existing_translation : translator.translate(key)
81
- end
82
- end
88
+ ret, threads = {}, []
89
+ keys.each do |key|
90
+ threads << Thread.new do
91
+ Rails.logger.debug "translating #{key} ..."
92
+ Thread.pass
93
+ key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
94
+ existing_translation = I18n.backend.send(:lookup, locale_name, key_suffix, key_prefix)
95
+ ret[key] = existing_translation ? existing_translation : translator.translate(key_suffix)
83
96
  end
84
- threads.each {|t| t.join}
85
97
  end
98
+ threads.each {|t| t.join}
99
+ ret
86
100
  end
87
101
 
88
102
  def locale_name
@@ -93,6 +107,20 @@ class I18nTranslationGenerator < Rails::Generators::NamedBase
93
107
  !!@include_timestamps
94
108
  end
95
109
 
110
+ # transform a Hash into a nested OrderedHash
111
+ def order_hash(hash)
112
+ ActiveSupport::OrderedHash.new.tap do |oh|
113
+ hash.sort_by {|k, _v| k}.each do |key, value|
114
+ if key.to_s.include? '.'
115
+ key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
116
+ key_prefix.inject(oh) {|h, k| h[k] ||= ActiveSupport::OrderedHash.new}[key_suffix] = value
117
+ else
118
+ oh[key] = value
119
+ end
120
+ end
121
+ end
122
+ end
123
+
96
124
  # iterate through all values
97
125
  def each_value(parents, src, &block)
98
126
  src.each do |k, v|
@@ -1,7 +1,7 @@
1
1
  begin
2
2
  require 'psych'
3
3
  rescue LoadError
4
- require File.join(File.dirname(__FILE__), 'yaml_waml')
4
+ require 'generators/i18n_translation/lib/yaml_waml'
5
5
  end
6
6
 
7
7
  module I27r
@@ -10,7 +10,7 @@ module I27r
10
10
  delegate :scan, :to => :@text
11
11
 
12
12
  def initialize(text, options = {})
13
- @generated = !!options[:generated] || text.ends_with?(' #g')
13
+ @generated = !!options[:generated] || text.end_with?(' #g')
14
14
  @yaml = YAML.load text.to_s + ' '
15
15
  @text = text
16
16
  end
@@ -43,7 +43,7 @@ module I27r
43
43
  end
44
44
 
45
45
  def to_s
46
- "#{@text}#{' #g' if generated? && yaml? && !value.nil? && !@text.ends_with?(' #g')}"
46
+ "#{@text}#{' #g' if generated? && yaml? && !value.nil? && !@text.end_with?(' #g')}"
47
47
  end
48
48
 
49
49
  private
@@ -127,7 +127,7 @@ module I27r
127
127
  previous_indent = ''
128
128
  ''.tap do |ret|
129
129
  @lines.each do |line|
130
- ret << "\n" if add_blank_line && (line.indent < previous_indent) && !line.to_s.blank? && !ret.ends_with?("\n\n")
130
+ ret << "\n" if add_blank_line && (line.indent < previous_indent) && !line.to_s.blank? && !ret.end_with?("\n\n")
131
131
  previous_indent = line.indent
132
132
  ret << line.to_s << "\n"
133
133
  end
@@ -1,3 +1,3 @@
1
1
  module I18nGenerators
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -1,25 +1,26 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '/../generators/i18n_locale/i18n_locale_command')
1
+ require 'spec_helper'
2
+ require 'generators/i18n_locale/i18n_locale_generator'
3
3
 
4
- describe I18nGenerator::Generator::Commands::Create do
5
- before do
6
- (@command = Object.new).extend I18nGenerator::Generator::Commands::Create
7
- @command.stub!(:locale_name).and_return('ja')
8
- end
4
+ describe I18nLocaleGenerator do
5
+ subject { I18nLocaleGenerator.new(['ja']) }
9
6
 
10
7
  describe 'add_locale_config' do
11
8
  describe 'when i18n.default_locale is configured in environment.rb' do
12
9
  before do
13
10
  @config = "
14
- Rails::Initializer.run do |config|
15
- config.i18n.default_locale = :de
11
+ module Tes
12
+ class Application < Rails::Application
13
+ config.i18n.default_locale = :de
14
+ end
16
15
  end"
17
16
  end
18
17
 
19
18
  it 'rewrites the existing default_locale to locale_name value' do
20
- @command.send(:add_locale_config, @config).should == "
21
- Rails::Initializer.run do |config|
22
- config.i18n.default_locale = 'ja'
19
+ subject.send(:add_locale_config, @config).should == "
20
+ module Tes
21
+ class Application < Rails::Application
22
+ config.i18n.default_locale = 'ja'
23
+ end
23
24
  end"
24
25
  end
25
26
  end
@@ -27,15 +28,19 @@ end"
27
28
  describe 'when i18n.default_locale config is commented in environment.rb' do
28
29
  before do
29
30
  @config = "
30
- Rails::Initializer.run do |config|
31
- # config.i18n.default_locale = :de
31
+ module Tes
32
+ class Application < Rails::Application
33
+ # config.i18n.default_locale = :de
34
+ end
32
35
  end"
33
36
  end
34
37
 
35
38
  it 'uncomments the existing commented i18n config and sets locale_name value' do
36
- @command.send(:add_locale_config, @config).should == "
37
- Rails::Initializer.run do |config|
38
- config.i18n.default_locale = 'ja'
39
+ subject.send(:add_locale_config, @config).should == "
40
+ module Tes
41
+ class Application < Rails::Application
42
+ config.i18n.default_locale = 'ja'
43
+ end
39
44
  end"
40
45
  end
41
46
  end
@@ -43,21 +48,24 @@ end"
43
48
  describe 'when i18n.default_locale is not written in environment.rb' do
44
49
  before do
45
50
  @config = "
46
- Rails::Initializer.run do |config|
47
- something goes here.
48
- bla bla bla...
51
+ module Tes
52
+ class Application < Rails::Application
53
+ something goes here.
54
+ bla bla bla...
55
+ end
49
56
  end"
50
57
  end
51
58
 
52
59
  it 'adds the default_locale config inside the config block and sets locale_name value' do
53
- @command.send(:add_locale_config, @config).should == "
54
- Rails::Initializer.run do |config|
55
- config.i18n.default_locale = 'ja'
56
- something goes here.
57
- bla bla bla...
60
+ subject.send(:add_locale_config, @config).should == "
61
+ module Tes
62
+ class Application < Rails::Application
63
+ config.i18n.default_locale = 'ja'
64
+ something goes here.
65
+ bla bla bla...
66
+ end
58
67
  end"
59
68
  end
60
69
  end
61
70
  end
62
71
  end
63
-
@@ -1,24 +1,20 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper')
2
- require File.join(File.dirname(__FILE__), '/../generators/i18n_translation/i18n_translation_command')
1
+ require 'spec_helper'
2
+ require 'generators/i18n_translation/i18n_translation_generator'
3
3
 
4
- describe I18nGenerator::Generator::Commands::Create do
5
- before do
6
- (@command = Object.new).extend I18nGenerator::Generator::Commands::Create
7
- @command.stub!(:locale_name).and_return('ja')
8
- end
4
+ describe I18nTranslationGenerator do
5
+ subject { I18nTranslationGenerator.new(['ja']) }
9
6
 
10
7
  describe 'each_value' do
11
- it 'iterates through each value' do
8
+ xit 'iterates through each value' do
12
9
  hash = ActiveSupport::OrderedHash.new
13
10
  hash[:parent1] = ActiveSupport::OrderedHash.new
14
11
  hash[:parent1][:child1] = 'child one'
15
12
  hash[:parent2] = ActiveSupport::OrderedHash.new
16
13
  hash[:parent2][:child2] = 'child two'
17
14
  hash[:parent2][:child3] = 'child three'
18
- @command.__send__(:each_value, [], hash) do |parents, value|
15
+ subject.send(:each_value, [], hash) do |parents, value|
19
16
  p "#{parents.join('.')} #{value}"
20
17
  end
21
18
  end
22
19
  end
23
20
  end
24
-
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,14 @@
1
- require 'active_support/all'
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rails'
4
+ require 'rails/generators'
2
5
 
3
6
  # Requires supporting files with custom matchers and macros, etc,
4
7
  # in ./support/ and its subdirectories.
5
8
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
6
9
 
10
+ Rails.logger ||= Logger.new STDOUT
11
+
7
12
  RSpec.configure do |config|
8
13
  # config.mock_with :rr
9
14
  config.mock_with :rspec
@@ -1,46 +1,39 @@
1
+ # coding: utf-8
1
2
  $KCODE = 'U'
2
3
 
3
- require File.join(File.dirname(__FILE__), 'spec_helper')
4
- require File.join(File.dirname(__FILE__), '../generators/i18n_translation/lib/translator')
5
- include I18nTranslationGeneratorModule
4
+ require 'spec_helper'
5
+ require 'generators/i18n_translation/lib/translator'
6
6
 
7
- describe Translator do
8
- before(:each) do
9
- @translator = Translator.new 'ja'
10
- end
7
+ describe I27r::Translator do
8
+ subject { I27r::Translator.new 'ja' }
11
9
 
12
10
  describe 'when successfully translated' do
13
11
  before do
14
- res_200 = mock('res_200')
15
- res_200.stub!(:read).and_return('{"responseData": {"translatedText":"こんにちは"}, "responseDetails": null, "responseStatus": 200}')
16
- OpenURI.stub!(:open_uri).and_return(res_200)
12
+ subject.stub!(:_translate).and_return('こんにちは')
17
13
  end
18
14
 
19
15
  it 'returns translated text' do
20
- @translator.translate('hello').should == 'こんにちは'
16
+ subject.translate('hello').should == 'こんにちは'
21
17
  end
22
18
  end
23
19
 
24
20
  describe 'when translation failed with error code' do
25
21
  before do
26
- res_500 = mock('res_500')
27
- res_500.stub!(:read).and_return('{"responseData": {"translatedText":"こんにちは?"}, "responseDetails": null, "responseStatus": 500}')
28
- OpenURI.stub!(:open_uri).and_return(res_500)
22
+ subject.stub!(:_translate).and_return('')
29
23
  end
30
24
 
31
25
  it 'returns the original text' do
32
- @translator.translate('hello').should == 'hello'
26
+ subject.translate('hello').should == 'hello'
33
27
  end
34
28
  end
35
29
 
36
30
  describe 'when translation raised an error' do
37
31
  before do
38
- OpenURI.stub!(:open_uri).and_raise('ERROR!')
32
+ subject.stub!(:_translate).and_raise('ERROR!')
39
33
  end
40
34
 
41
35
  it 'returns the original text' do
42
- @translator.translate('hello').should == 'hello'
36
+ subject.translate('hello').should == 'hello'
43
37
  end
44
38
  end
45
39
  end
46
-