simonmenke-globalize2 0.0.1

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 (43) hide show
  1. data/LICENSE +21 -0
  2. data/README.textile +202 -0
  3. data/generators/db_backend.rb +0 -0
  4. data/generators/templates/db_backend_migration.rb +25 -0
  5. data/init.rb +1 -0
  6. data/lib/globalize/backend/chain.rb +102 -0
  7. data/lib/globalize/backend/pluralizing.rb +37 -0
  8. data/lib/globalize/backend/static.rb +60 -0
  9. data/lib/globalize/i18n/missing_translations_log_handler.rb +41 -0
  10. data/lib/globalize/i18n/missing_translations_raise_handler.rb +27 -0
  11. data/lib/globalize/load_path.rb +63 -0
  12. data/lib/globalize/locale/fallbacks.rb +63 -0
  13. data/lib/globalize/locale/language_tag.rb +81 -0
  14. data/lib/globalize/model/active_record.rb +38 -0
  15. data/lib/globalize/model/active_record/adapter.rb +96 -0
  16. data/lib/globalize/model/active_record/translated.rb +154 -0
  17. data/lib/globalize/translation.rb +32 -0
  18. data/lib/locale/root.yml +3 -0
  19. data/lib/rails_edge_load_path_patch.rb +40 -0
  20. data/notes.textile +51 -0
  21. data/rails/init.rb +9 -0
  22. data/test/backends/chained_test.rb +175 -0
  23. data/test/backends/pluralizing_test.rb +63 -0
  24. data/test/backends/static_test.rb +143 -0
  25. data/test/data/locale/all.yml +2 -0
  26. data/test/data/locale/de-DE.yml +2 -0
  27. data/test/data/locale/en-US.yml +2 -0
  28. data/test/data/locale/en-US/module.yml +2 -0
  29. data/test/data/locale/fi-FI/module.yml +2 -0
  30. data/test/data/locale/root.yml +0 -0
  31. data/test/data/no_globalize_schema.rb +11 -0
  32. data/test/data/post.rb +24 -0
  33. data/test/data/schema.rb +39 -0
  34. data/test/i18n/missing_translations_test.rb +36 -0
  35. data/test/load_path_test.rb +49 -0
  36. data/test/locale/fallbacks_test.rb +154 -0
  37. data/test/locale/language_tag_test.rb +130 -0
  38. data/test/model/active_record/migration_test.rb +73 -0
  39. data/test/model/active_record/sti_translated_test.rb +75 -0
  40. data/test/model/active_record/translated_test.rb +458 -0
  41. data/test/test_helper.rb +26 -0
  42. data/test/translation_test.rb +54 -0
  43. metadata +114 -0
@@ -0,0 +1,2 @@
1
+ en-US:
2
+ from-all-file: From the "all" file.
@@ -0,0 +1,2 @@
1
+ de-DE:
2
+ from-locale-file: Aus der Locale Datei.
@@ -0,0 +1,2 @@
1
+ en-US:
2
+ from-locale-file: From the locale file.
@@ -0,0 +1,2 @@
1
+ en-US:
2
+ from-locale-dir: From the locale directory.
@@ -0,0 +1,2 @@
1
+ fi-FI:
2
+ from-locale-dir: Locale hakemistosta.
File without changes
@@ -0,0 +1,11 @@
1
+ # This schema creates tables without columns for the translated fields
2
+ ActiveRecord::Schema.define do
3
+ create_table :blogs, :force => true do |t|
4
+ t.string :name
5
+ end
6
+
7
+ create_table :posts, :force => true do |t|
8
+ t.references :blog
9
+ end
10
+ end
11
+
data/test/data/post.rb ADDED
@@ -0,0 +1,24 @@
1
+ class Post < ActiveRecord::Base
2
+ translates :subject, :content
3
+ validates_presence_of :subject
4
+ end
5
+
6
+ class Blog < ActiveRecord::Base
7
+ has_many :posts, :order => 'id ASC'
8
+ end
9
+
10
+ class Parent < ActiveRecord::Base
11
+ translates :content
12
+ end
13
+
14
+ class Child < Parent
15
+ end
16
+
17
+ class Comment < ActiveRecord::Base
18
+ validates_presence_of :content
19
+ belongs_to :post
20
+ end
21
+
22
+ class TranslatedComment < Comment
23
+ translates :content
24
+ end
@@ -0,0 +1,39 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ create_table :blogs, :force => true do |t|
4
+ t.string :description
5
+ end
6
+
7
+ create_table :posts, :force => true do |t|
8
+ t.references :blog
9
+ end
10
+
11
+ create_table :post_translations, :force => true do |t|
12
+ t.string :locale
13
+ t.references :post
14
+ t.string :subject
15
+ t.text :content
16
+ end
17
+
18
+ create_table :parents, :force => true do |t|
19
+ end
20
+
21
+ create_table :parent_translations, :force => true do |t|
22
+ t.string :locale
23
+ t.references :parent
24
+ t.text :content
25
+ t.string :type
26
+ end
27
+
28
+ create_table :comments, :force => true do |t|
29
+ t.references :post
30
+ end
31
+
32
+ create_table :translated_comment_translations, :force => true do |t|
33
+ t.string :locale
34
+ t.references :comment
35
+ t.string :subject
36
+ t.text :content
37
+ end
38
+
39
+ end
@@ -0,0 +1,36 @@
1
+ require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2
+ require 'globalize/i18n/missing_translations_log_handler'
3
+
4
+ class MissingTranslationsTest < ActiveSupport::TestCase
5
+ test "defines I18n.missing_translations_logger accessor" do
6
+ assert I18n.respond_to?(:missing_translations_logger)
7
+ end
8
+
9
+ test "defines I18n.missing_translations_logger= writer" do
10
+ assert I18n.respond_to?(:missing_translations_logger=)
11
+ end
12
+ end
13
+
14
+ class TestLogger < String
15
+ def warn(msg) self.concat msg; end
16
+ end
17
+
18
+ class LogMissingTranslationsTest < ActiveSupport::TestCase
19
+ def setup
20
+ @locale, @key, @options = :en, :foo, {}
21
+ @exception = I18n::MissingTranslationData.new(@locale, @key, @options)
22
+
23
+ @logger = TestLogger.new
24
+ I18n.missing_translations_logger = @logger
25
+ end
26
+
27
+ test "still returns the exception message for MissingTranslationData exceptions" do
28
+ result = I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
29
+ assert_equal 'translation missing: en, foo', result
30
+ end
31
+
32
+ test "logs the missing translation to I18n.missing_translations_logger" do
33
+ I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
34
+ assert_equal 'translation missing: en, foo', @logger
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ require File.join( File.dirname(__FILE__), 'test_helper' )
2
+ require 'globalize/load_path'
3
+
4
+ class LoadPathTest < ActiveSupport::TestCase
5
+ def setup
6
+ @plugin_dir = "#{File.dirname(__FILE__)}/.."
7
+ @locale_dir = "#{File.dirname(__FILE__)}/data/locale"
8
+ @load_path = Globalize::LoadPath.new
9
+ end
10
+
11
+ test "returns glob patterns for all locales and ruby + yaml files by default" do
12
+ patterns = %w(locales/all.rb
13
+ locales/*.rb
14
+ locales/*/**/*.rb
15
+ locales/all.yml
16
+ locales/*.yml
17
+ locales/*/**/*.yml)
18
+ assert_equal patterns, @load_path.send(:patterns, 'locales')
19
+ end
20
+
21
+ test "returns the glob patterns for registered locales and extensions" do
22
+ @load_path.locales = [:en, :de]
23
+ @load_path.extensions = [:sql]
24
+ patterns = %w(locales/all.sql
25
+ locales/en.sql
26
+ locales/en/**/*.sql
27
+ locales/de.sql
28
+ locales/de/**/*.sql)
29
+ assert_equal patterns, @load_path.send(:patterns, 'locales')
30
+ end
31
+
32
+ test "expands paths using yml as a default file extension" do
33
+ @load_path << @locale_dir
34
+ expected = %w(all.yml de-DE.yml en-US.yml en-US/module.yml fi-FI/module.yml root.yml)
35
+ assert_equal expected, @load_path.map{|path| path.sub("#{@locale_dir}\/", '')}
36
+ end
37
+
38
+ test "appends new paths to the collection so earlier collected paths preceed later collected ones" do
39
+ @load_path.locales = [:root]
40
+ @load_path << "#{@plugin_dir}/lib/locale"
41
+ @load_path << @locale_dir
42
+
43
+ expected = %W(#{@plugin_dir}/lib/locale/root.yml
44
+ #{@locale_dir}/all.yml
45
+ #{@locale_dir}/root.yml)
46
+ assert_equal expected, @load_path
47
+ end
48
+
49
+ end
@@ -0,0 +1,154 @@
1
+ require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2
+ require 'globalize/locale/fallbacks'
3
+
4
+ include Globalize::Locale
5
+ I18n.default_locale = :'en-US' # This has to be set explicitly, no longer default for I18n
6
+
7
+ class FallbacksTest < ActiveSupport::TestCase
8
+ def setup
9
+ I18n.fallbacks = Fallbacks.new
10
+ end
11
+
12
+ def teardown
13
+ I18n.default_locale = :'en-US'
14
+ end
15
+
16
+ test "#[] caches computed results" do
17
+ I18n.fallbacks['en']
18
+ assert_equal( { :en => [:en, :"en-US", :root] }, I18n.fallbacks )
19
+ end
20
+
21
+ test "#defaults always reflect the I18n.default_locale if no default has been set manually" do
22
+ I18n.default_locale = :'en-US'
23
+ assert_equal( [:'en-US', :en, :root], I18n.fallbacks.defaults )
24
+ end
25
+
26
+ test "#defaults always reflect a manually passed default locale if any" do
27
+ I18n.fallbacks = Fallbacks.new(:'fi-FI')
28
+ assert_equal( [:'fi-FI', :fi, :root], I18n.fallbacks.defaults )
29
+ I18n.default_locale = :'de-DE'
30
+ assert_equal( [:'fi-FI', :fi, :root], I18n.fallbacks.defaults )
31
+ end
32
+
33
+ test "#defaults allows to set multiple defaults" do
34
+ I18n.fallbacks = Fallbacks.new(:'fi-FI', :'se-FI')
35
+ assert_equal( [:'fi-FI', :fi, :'se-FI', :se, :root], I18n.fallbacks.defaults )
36
+ end
37
+ end
38
+
39
+ class NoMappingFallbacksTest < ActiveSupport::TestCase
40
+ def setup
41
+ @fallbacks = Fallbacks.new(:'en-US')
42
+ end
43
+
44
+ test "returns [:es, :en-US, :root] for :es" do
45
+ assert_equal [:es, :"en-US", :en, :root], @fallbacks[:es]
46
+ end
47
+
48
+ test "returns [:es-ES, :es, :en-US, :root] for :es-ES" do
49
+ assert_equal [:"es-ES", :es, :"en-US", :en, :root], @fallbacks[:"es-ES"]
50
+ end
51
+
52
+ test "returns [:es-MX, :es, :en-US, :root] for :es-MX" do
53
+ assert_equal [:"es-MX", :es, :"en-US", :en, :root], @fallbacks[:"es-MX"]
54
+ end
55
+
56
+ test "returns [:es-Latn-ES, :es-Latn, :es, :en-US, :root] for :es-Latn-ES" do
57
+ assert_equal [:"es-Latn-ES", :"es-Latn", :es, :"en-US", :en, :root], @fallbacks[:'es-Latn-ES']
58
+ end
59
+
60
+ test "returns [:en, :en-US, :root] for :en" do
61
+ assert_equal [:en, :"en-US", :root], @fallbacks[:en]
62
+ end
63
+
64
+ test "returns [:en-US, :en, :root] for :en-US (special case: locale == default)" do
65
+ assert_equal [:"en-US", :en, :root], @fallbacks[:"en-US"]
66
+ end
67
+ end
68
+
69
+ class CaMappingFallbacksTest < ActiveSupport::TestCase
70
+ # Most people who speak Catalan also live in Spain, so test is safe to assume
71
+ # that they also speak Spanish as spoken in Spain.
72
+ def setup
73
+ @fallbacks = Fallbacks.new(:'en-US')
74
+ @fallbacks.map :ca => :"es-ES"
75
+ end
76
+
77
+ test "returns [:ca, :es-ES, :es, :en-US, :root] for :ca" do
78
+ assert_equal [:ca, :"es-ES", :es, :"en-US", :en, :root], @fallbacks[:ca]
79
+ end
80
+
81
+ test "returns [:ca-ES, :ca, :es-ES, :es, :en-US, :root] for :ca-ES" do
82
+ assert_equal [:"ca-ES", :ca, :"es-ES", :es, :"en-US", :en, :root], @fallbacks[:"ca-ES"]
83
+ end
84
+ end
85
+
86
+ class ArMappingFallbacksTest < ActiveSupport::TestCase
87
+ # People who speak Arabic as spoken in Palestine often times also speak
88
+ # Hebrew as spoken in Israel. However test is in no way safe to assume that
89
+ # everybody who speaks Arabic also speaks Hebrew.
90
+ def setup
91
+ @fallbacks = Fallbacks.new(:'en-US')
92
+ @fallbacks.map :"ar-PS" => :"he-IL"
93
+ end
94
+
95
+ test "returns [:ar, :en-US, :root] for :ar" do
96
+ assert_equal [:ar, :"en-US", :en, :root], @fallbacks[:ar]
97
+ end
98
+
99
+ test "returns [:ar-EG, :ar, :en-US, :root] for :ar-EG" do
100
+ assert_equal [:"ar-EG", :ar, :"en-US", :en, :root], @fallbacks[:"ar-EG"]
101
+ end
102
+
103
+ test "returns [:ar-PS, :ar, :he-IL, :he, :en-US, :root] for :ar-PS" do
104
+ assert_equal [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en, :root], @fallbacks[:"ar-PS"]
105
+ end
106
+ end
107
+
108
+ class SmsMappingFallbacksTest < ActiveSupport::TestCase
109
+ # Sami people live in several scandinavian countries. In Finnland many people
110
+ # know Swedish and Finnish. Thus, test can be assumed that Sami living in
111
+ # Finnland also speak Swedish and Finnish.
112
+ def setup
113
+ @fallbacks = Fallbacks.new(:'en-US')
114
+ @fallbacks.map :sms => [:"se-FI", :"fi-FI"]
115
+ end
116
+
117
+ test "returns [:sms-FI, :sms, :se-FI, :se, :fi-FI, :fi, :en-US, :root] for :sms-FI" do
118
+ assert_equal [:"sms-FI", :sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en, :root], @fallbacks[:"sms-FI"]
119
+ end
120
+ end
121
+
122
+ class DeAtMappingFallbacksTest < ActiveSupport::TestCase
123
+ def setup
124
+ @fallbacks = Fallbacks.new(:'en-US')
125
+ @fallbacks.map :"de-AT" => :"de-DE"
126
+ end
127
+
128
+ test "returns [:de, :en-US, :root] for de" do
129
+ assert_equal [:de, :"en-US", :en, :root], @fallbacks[:"de"]
130
+ end
131
+
132
+ test "returns [:de-DE, :de, :en-US, :root] for de-DE" do
133
+ assert_equal [:"de-DE", :de, :"en-US", :en, :root], @fallbacks[:"de-DE"]
134
+ end
135
+
136
+ test "returns [:de-AT, :de, :de-DE, :en-US, :root] for de-AT" do
137
+ assert_equal [:"de-AT", :de, :"de-DE", :"en-US", :en, :root], @fallbacks[:"de-AT"]
138
+ end
139
+ end
140
+
141
+ class DeMappingFallbacksTest < ActiveSupport::TestCase
142
+ def setup
143
+ @fallbacks = Fallbacks.new(:'en-US')
144
+ @fallbacks.map :de => :en, :he => :en
145
+ end
146
+
147
+ test "returns [:de, :en, :root] for :de" do
148
+ assert_equal [:de, :en, :"en-US", :root], @fallbacks[:de]
149
+ end
150
+
151
+ test "returns [:he, :en, :root] for :de" do
152
+ assert_equal [:he, :en, :"en-US", :root], @fallbacks[:he]
153
+ end
154
+ end
@@ -0,0 +1,130 @@
1
+ require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2
+ require 'globalize/locale/language_tag'
3
+
4
+ include Globalize::Locale
5
+
6
+ class LanguageTagTest < ActiveSupport::TestCase
7
+ test "given a valid tag 'de' returns an LanguageTag from #tag" do
8
+ assert_instance_of LanguageTag, LanguageTag.tag('de')
9
+ end
10
+
11
+ test "given a valid tag 'de' returns an array of subtags" do
12
+ assert_equal ['de', nil, nil, nil, nil, nil, nil], LanguageTag::SimpleParser.match('de')
13
+ end
14
+
15
+ test "given a valid tag 'de-DE' returns an array of subtags" do
16
+ assert_equal ['de', nil, 'DE', nil, nil, nil, nil], LanguageTag::SimpleParser.match('de-DE')
17
+ end
18
+
19
+ test "given a valid lowercase tag 'de-latn-de-variant-x-phonebk' returns an array of subtags" do
20
+ assert_equal ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil],
21
+ LanguageTag::SimpleParser.match('de-latn-de-variant-x-phonebk')
22
+ end
23
+
24
+ test "given a valid uppercase tag 'DE-LATN-DE-VARIANT-X-PHONEBK' returns an array of subtags" do
25
+ assert_equal ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil],
26
+ LanguageTag::SimpleParser.match('DE-LATN-DE-VARIANT-X-PHONEBK')
27
+ end
28
+
29
+ test "given an invalid tag 'a-DE' test returns false" do
30
+ assert !LanguageTag::SimpleParser.match('a-DE')
31
+ end
32
+
33
+ test "given an invalid tag 'de-419-DE' test returns false" do
34
+ assert !LanguageTag::SimpleParser.match('de-419-DE')
35
+ end
36
+ end
37
+
38
+ class DeLatnLanguageTagTest < ActiveSupport::TestCase
39
+ def setup
40
+ subtags = %w(de Latn DE variant a-ext x-phonebk i-klingon)
41
+ @tag = LanguageTag.new *subtags
42
+ end
43
+
44
+ test "returns 'de' as the language subtag in lowercase" do
45
+ assert_equal 'de', @tag.language
46
+ end
47
+
48
+ test "returns 'Latn' as the script subtag in titlecase" do
49
+ assert_equal 'Latn', @tag.script
50
+ end
51
+
52
+ test "returns 'DE' as the region subtag in uppercase" do
53
+ assert_equal 'DE', @tag.region
54
+ end
55
+
56
+ test "returns 'variant' as the variant subtag in lowercase" do
57
+ assert_equal 'variant', @tag.variant
58
+ end
59
+
60
+ test "returns 'a-ext' as the extension subtag" do
61
+ assert_equal 'a-ext', @tag.extension
62
+ end
63
+
64
+ test "returns 'x-phonebk' as the privateuse subtag" do
65
+ assert_equal 'x-phonebk', @tag.privateuse
66
+ end
67
+
68
+ test "returns 'i-klingon' as the grandfathered subtag" do
69
+ assert_equal 'i-klingon', @tag.grandfathered
70
+ end
71
+
72
+ test "returns a formatted tag string from #to_s" do
73
+ assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon', @tag.to_s
74
+ end
75
+
76
+ test "returns an array containing the formatted subtags from #to_a" do
77
+ assert_equal %w(de Latn DE variant a-ext x-phonebk i-klingon), @tag.to_a
78
+ end
79
+ end
80
+
81
+ class InheritanceLanguageTagTest < ActiveSupport::TestCase
82
+ test "returns 'de-Latn-DE-variant-a-ext-x-phonebk' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
83
+ tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
84
+ assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk', tag.parent.to_s
85
+ end
86
+
87
+ test "returns 'de-Latn-DE-variant-a-ext' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk'" do
88
+ tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk)
89
+ assert_equal 'de-Latn-DE-variant-a-ext', tag.parent.to_s
90
+ end
91
+
92
+ test "returns 'de-Latn-DE-variant' as the parent of 'de-Latn-DE-variant-a-ext'" do
93
+ tag = LanguageTag.new *%w(de Latn DE variant a-ext)
94
+ assert_equal 'de-Latn-DE-variant', tag.parent.to_s
95
+ end
96
+
97
+ test "returns 'de-Latn-DE' as the parent of 'de-Latn-DE-variant'" do
98
+ tag = LanguageTag.new *%w(de Latn DE variant)
99
+ assert_equal 'de-Latn-DE', tag.parent.to_s
100
+ end
101
+
102
+ test "returns 'de-Latn' as the parent of 'de-Latn-DE'" do
103
+ tag = LanguageTag.new *%w(de Latn DE)
104
+ assert_equal 'de-Latn', tag.parent.to_s
105
+ end
106
+
107
+ test "returns 'de' as the parent of 'de-Latn'" do
108
+ tag = LanguageTag.new *%w(de Latn)
109
+ assert_equal 'de', tag.parent.to_s
110
+ end
111
+
112
+ # TODO RFC4647 says: "If no language tag matches the request, the "default" value is returned."
113
+ # where should we set the default language?
114
+ # test "returns '' as the parent of 'de'" do
115
+ # tag = LanguageTag.new *%w(de)
116
+ # assert_equal '', tag.parent.to_s
117
+ # end
118
+
119
+ test "returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
120
+ parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon
121
+ de-Latn-DE-variant-a-ext-x-phonebk
122
+ de-Latn-DE-variant-a-ext
123
+ de-Latn-DE-variant
124
+ de-Latn-DE
125
+ de-Latn
126
+ de)
127
+ tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
128
+ assert_equal parents, tag.parents.map{|tag| tag.to_s}
129
+ end
130
+ end