globalize2 0.1.0 → 0.2.0
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.
- data/.gitignore +2 -1
- data/README.textile +27 -143
- data/VERSION +1 -1
- data/generators/templates/db_backend_migration.rb +3 -3
- data/globalize2.gemspec +30 -49
- data/init.rb +1 -8
- data/lib/globalize.rb +15 -0
- data/lib/globalize/active_record.rb +195 -0
- data/lib/globalize/active_record/adapter.rb +80 -0
- data/lib/globalize/active_record/attributes.rb +25 -0
- data/lib/globalize/active_record/migration.rb +40 -0
- data/lib/{globalize/i18n → i18n}/missing_translations_log_handler.rb +8 -8
- data/lib/{globalize/i18n → i18n}/missing_translations_raise_handler.rb +3 -5
- data/test/active_record/fallbacks_test.rb +102 -0
- data/test/{model/active_record → active_record}/migration_test.rb +21 -26
- data/test/{model/active_record → active_record}/sti_translated_test.rb +4 -30
- data/test/active_record/translates_test.rb +87 -0
- data/test/active_record/translation_class_test.rb +30 -0
- data/test/active_record/validation_tests.rb +75 -0
- data/test/active_record_test.rb +451 -0
- data/test/data/models.rb +16 -0
- data/test/data/schema.rb +23 -7
- data/test/i18n/missing_translations_test.rb +6 -6
- data/test/test_helper.rb +55 -15
- metadata +33 -46
- data/lib/globalize/backend/chain.rb +0 -102
- data/lib/globalize/backend/pluralizing.rb +0 -37
- data/lib/globalize/backend/static.rb +0 -61
- data/lib/globalize/load_path.rb +0 -63
- data/lib/globalize/locale/fallbacks.rb +0 -63
- data/lib/globalize/locale/language_tag.rb +0 -81
- data/lib/globalize/model/active_record.rb +0 -56
- data/lib/globalize/model/active_record/adapter.rb +0 -100
- data/lib/globalize/model/active_record/translated.rb +0 -174
- data/lib/globalize/translation.rb +0 -32
- data/lib/locale/root.yml +0 -3
- data/lib/rails_edge_load_path_patch.rb +0 -40
- data/notes.textile +0 -51
- data/test/backends/chained_test.rb +0 -175
- data/test/backends/pluralizing_test.rb +0 -63
- data/test/backends/static_test.rb +0 -147
- data/test/data/locale/all.yml +0 -2
- data/test/data/locale/de-DE.yml +0 -2
- data/test/data/locale/en-US.yml +0 -2
- data/test/data/locale/en-US/module.yml +0 -2
- data/test/data/locale/fi-FI/module.yml +0 -2
- data/test/data/locale/root.yml +0 -0
- data/test/load_path_test.rb +0 -49
- data/test/locale/fallbacks_test.rb +0 -154
- data/test/locale/language_tag_test.rb +0 -130
- data/test/model/active_record/translated_test.rb +0 -487
- data/test/translation_test.rb +0 -54
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../data/models')
|
3
|
+
|
4
|
+
class TranslatesTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
I18n.locale = nil
|
7
|
+
ActiveRecord::Base.locale = nil
|
8
|
+
reset_db!
|
9
|
+
end
|
10
|
+
|
11
|
+
test 'defines a :locale accessors on ActiveRecord::Base' do
|
12
|
+
ActiveRecord::Base.locale = :de
|
13
|
+
assert_equal :de, ActiveRecord::Base.locale
|
14
|
+
end
|
15
|
+
|
16
|
+
test 'the :locale reader on ActiveRecord::Base does not default to I18n.locale (anymore)' do
|
17
|
+
I18n.locale = :en
|
18
|
+
assert_nil ActiveRecord::Base.locale
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'ActiveRecord::Base.with_locale temporarily sets the given locale and yields the block' do
|
22
|
+
I18n.locale = :en
|
23
|
+
post = Post.with_locale(:de) do
|
24
|
+
Post.create!(:subject => 'Titel', :content => 'Inhalt')
|
25
|
+
end
|
26
|
+
assert_nil Post.locale
|
27
|
+
assert_equal :en, I18n.locale
|
28
|
+
|
29
|
+
I18n.locale = :de
|
30
|
+
assert_equal 'Titel', post.subject
|
31
|
+
end
|
32
|
+
|
33
|
+
test 'translation_class returns the Translation class' do
|
34
|
+
assert_equal Post::Translation, Post.translation_class
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'defines a has_many association on the model class' do
|
38
|
+
assert_has_many Post, :translations
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'defines a scope for retrieving locales that have complete translations' do
|
42
|
+
post = Post.create!(:subject => 'subject', :content => 'content')
|
43
|
+
assert_equal [:en], post.translated_locales
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'sets the given attributes to translated_attribute_names' do
|
47
|
+
assert_equal [:subject, :content], Post.translated_attribute_names
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'defines accessors for the translated attributes' do
|
51
|
+
post = Post.new
|
52
|
+
assert post.respond_to?(:subject)
|
53
|
+
assert post.respond_to?(:subject=)
|
54
|
+
end
|
55
|
+
|
56
|
+
test 'attribute reader without arguments will use the current locale on ActiveRecord::Base or I18n' do
|
57
|
+
post = Post.with_locale(:de) do
|
58
|
+
Post.create!(:subject => 'Titel', :content => 'Inhalt')
|
59
|
+
end
|
60
|
+
I18n.locale = :de
|
61
|
+
assert_equal 'Titel', post.subject
|
62
|
+
|
63
|
+
I18n.locale = :en
|
64
|
+
ActiveRecord::Base.locale = :de
|
65
|
+
assert_equal 'Titel', post.subject
|
66
|
+
end
|
67
|
+
|
68
|
+
test 'attribute reader when passed a locale will use the given locale' do
|
69
|
+
post = Post.with_locale(:de) do
|
70
|
+
Post.create!(:subject => 'Titel', :content => 'Inhalt')
|
71
|
+
end
|
72
|
+
assert_equal 'Titel', post.subject(:de)
|
73
|
+
end
|
74
|
+
|
75
|
+
test 'attribute reader will use the current locale on ActiveRecord::Base or I18n' do
|
76
|
+
post = Post.with_locale(:en) do
|
77
|
+
Post.create!(:subject => 'title', :content => 'content')
|
78
|
+
end
|
79
|
+
I18n.locale = :de
|
80
|
+
post.subject = 'Titel'
|
81
|
+
assert_equal 'Titel', post.subject
|
82
|
+
|
83
|
+
ActiveRecord::Base.locale = :en
|
84
|
+
post.subject = 'title'
|
85
|
+
assert_equal 'title', post.subject
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../data/models')
|
3
|
+
|
4
|
+
class TranlationClassTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
reset_db!
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'defines a Translation class nested in the model class' do
|
10
|
+
assert Post.const_defined?(:Translation)
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'defines a belongs_to association' do
|
14
|
+
assert_belongs_to Post::Translation, :post
|
15
|
+
end
|
16
|
+
|
17
|
+
test 'defines a reader for :locale that always returns a symbol' do
|
18
|
+
post = Post::Translation.new
|
19
|
+
post.write_attribute('locale', 'de')
|
20
|
+
assert_equal :de, post.locale
|
21
|
+
end
|
22
|
+
|
23
|
+
test 'defines a write for :locale that always writes a string' do
|
24
|
+
post = Post::Translation.new
|
25
|
+
post.locale = :de
|
26
|
+
assert_equal 'de', post.read_attribute('locale')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../data/models')
|
3
|
+
|
4
|
+
class ValidationTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
reset_db!
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
Validatee.instance_variable_set(:@validate_callbacks, CallbackChain.new)
|
11
|
+
end
|
12
|
+
|
13
|
+
test "validates_presence_of" do
|
14
|
+
Validatee.class_eval { validates_presence_of :string }
|
15
|
+
assert !Validatee.new.valid?
|
16
|
+
assert Validatee.new(:string => 'foo').valid?
|
17
|
+
end
|
18
|
+
|
19
|
+
test "validates_confirmation_of" do
|
20
|
+
Validatee.class_eval { validates_confirmation_of :string }
|
21
|
+
assert !Validatee.new(:string => 'foo', :string_confirmation => 'bar').valid?
|
22
|
+
assert Validatee.new(:string => 'foo', :string_confirmation => 'foo').valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
test "validates_acceptance_of" do
|
26
|
+
Validatee.class_eval { validates_acceptance_of :string, :accept => '1' }
|
27
|
+
assert !Validatee.new(:string => '0').valid?
|
28
|
+
assert Validatee.new(:string => '1').valid?
|
29
|
+
end
|
30
|
+
|
31
|
+
test "validates_length_of (:is)" do
|
32
|
+
Validatee.class_eval { validates_length_of :string, :is => 1 }
|
33
|
+
assert !Validatee.new(:string => 'aa').valid?
|
34
|
+
assert Validatee.new(:string => 'a').valid?
|
35
|
+
end
|
36
|
+
|
37
|
+
test "validates_format_of" do
|
38
|
+
Validatee.class_eval { validates_format_of :string, :with => /^\d+$/ }
|
39
|
+
assert !Validatee.new(:string => 'a').valid?
|
40
|
+
assert Validatee.new(:string => '1').valid?
|
41
|
+
end
|
42
|
+
|
43
|
+
test "validates_inclusion_of" do
|
44
|
+
Validatee.class_eval { validates_inclusion_of :string, :in => %(a) }
|
45
|
+
assert !Validatee.new(:string => 'b').valid?
|
46
|
+
assert Validatee.new(:string => 'a').valid?
|
47
|
+
end
|
48
|
+
|
49
|
+
test "validates_exclusion_of" do
|
50
|
+
Validatee.class_eval { validates_exclusion_of :string, :in => %(b) }
|
51
|
+
assert !Validatee.new(:string => 'b').valid?
|
52
|
+
assert Validatee.new(:string => 'a').valid?
|
53
|
+
end
|
54
|
+
|
55
|
+
test "validates_numericality_of" do
|
56
|
+
Validatee.class_eval { validates_numericality_of :string }
|
57
|
+
assert !Validatee.new(:string => 'a').valid?
|
58
|
+
assert Validatee.new(:string => '1').valid?
|
59
|
+
end
|
60
|
+
|
61
|
+
# This doesn't pass and Rails' validates_uniqueness_of implementation doesn't
|
62
|
+
# seem to be extensible easily. One can work around that by either defining
|
63
|
+
# a custom validation on the Validatee model itself, or by using validates_uniqueness_of
|
64
|
+
# on Validatee::Translation.
|
65
|
+
#
|
66
|
+
# test "validates_uniqueness_of" do
|
67
|
+
# Validatee.class_eval { validates_uniqueness_of :string }
|
68
|
+
# Validatee.create!(:string => 'a')
|
69
|
+
# assert !Validatee.new(:string => 'a').valid?
|
70
|
+
# assert Validatee.new(:string => 'b').valid?
|
71
|
+
# end
|
72
|
+
|
73
|
+
# test "validates_associated" do
|
74
|
+
# end
|
75
|
+
end
|
@@ -0,0 +1,451 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/data/models')
|
3
|
+
|
4
|
+
# Higher level tests.
|
5
|
+
|
6
|
+
class ActiveRecordTest < ActiveSupport::TestCase
|
7
|
+
def setup
|
8
|
+
I18n.locale = :en
|
9
|
+
reset_db!
|
10
|
+
ActiveRecord::Base.locale = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def assert_translated(locale, record, names, expected)
|
14
|
+
I18n.locale = locale
|
15
|
+
assert_equal Array(expected), Array(names).map { |name| record.send(name) }
|
16
|
+
end
|
17
|
+
|
18
|
+
test "a translated record has translations" do
|
19
|
+
assert_equal [], Post.new.translations
|
20
|
+
end
|
21
|
+
|
22
|
+
test "saves a translated version of the record for each locale" do
|
23
|
+
post = Post.create(:subject => 'title')
|
24
|
+
I18n.locale = :de
|
25
|
+
post.update_attributes(:subject => 'Titel')
|
26
|
+
|
27
|
+
assert_equal 2, post.translations.size
|
28
|
+
assert_equal %w(de en), post.translations.map(&:locale).map(&:to_s).sort
|
29
|
+
assert_equal %w(Titel title), post.translations.map(&:subject).sort
|
30
|
+
end
|
31
|
+
|
32
|
+
test "a translated record has German translations" do
|
33
|
+
I18n.locale = :de
|
34
|
+
post = Post.create(:subject => 'foo')
|
35
|
+
assert_equal 1, post.translations.size
|
36
|
+
assert_equal [:de], post.translations.map { |t| t.locale }
|
37
|
+
end
|
38
|
+
|
39
|
+
test "modifiying translated fields while switching locales" do
|
40
|
+
post = Post.create(:subject => 'title', :content => 'content')
|
41
|
+
assert_equal %w(title content), [post.subject, post.content]
|
42
|
+
|
43
|
+
I18n.locale = :de
|
44
|
+
post.subject, post.content = 'Titel', 'Inhalt'
|
45
|
+
|
46
|
+
assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
|
47
|
+
assert_translated(:en, post, [:subject, :content], %w(title content))
|
48
|
+
assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
|
49
|
+
|
50
|
+
post.save
|
51
|
+
post.reload
|
52
|
+
|
53
|
+
assert_translated(:en, post, [:subject, :content], %w(title content))
|
54
|
+
assert_translated(:de, post, [:subject, :content], %w(Titel Inhalt))
|
55
|
+
end
|
56
|
+
|
57
|
+
test "attribute writers do return their argument" do
|
58
|
+
value = Post.new.subject = 'foo'
|
59
|
+
assert_equal 'foo', value
|
60
|
+
end
|
61
|
+
|
62
|
+
test "update_attribute succeeds with valid values" do
|
63
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
64
|
+
post.update_attribute(:subject, 'baz')
|
65
|
+
assert_equal 'baz', Post.first.subject
|
66
|
+
end
|
67
|
+
|
68
|
+
test "update_attributes fails with invalid values" do
|
69
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
70
|
+
assert !post.update_attributes(:subject => '')
|
71
|
+
assert_nil post.reload.attributes['subject']
|
72
|
+
assert_equal 'foo', post.subject
|
73
|
+
end
|
74
|
+
|
75
|
+
test "passing the locale to create uses the given locale" do
|
76
|
+
post = Post.create(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
|
77
|
+
assert_equal :en, I18n.locale
|
78
|
+
assert_nil ActiveRecord::Base.locale
|
79
|
+
|
80
|
+
I18n.locale = :de
|
81
|
+
assert_equal 'Titel', post.subject
|
82
|
+
end
|
83
|
+
|
84
|
+
test "passing the locale to attributes= uses the given locale" do
|
85
|
+
post = Post.create(:subject => 'title', :content => 'content')
|
86
|
+
post.update_attributes(:subject => 'Titel', :content => 'Inhalt', :locale => :de)
|
87
|
+
post.reload
|
88
|
+
|
89
|
+
assert_equal :en, I18n.locale
|
90
|
+
assert_nil ActiveRecord::Base.locale
|
91
|
+
|
92
|
+
assert_equal 'title', post.subject
|
93
|
+
I18n.locale = :de
|
94
|
+
assert_equal 'Titel', post.subject
|
95
|
+
end
|
96
|
+
|
97
|
+
test 'reload works' do
|
98
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
99
|
+
post.subject = 'baz'
|
100
|
+
post.reload
|
101
|
+
assert_equal 'foo', post.subject
|
102
|
+
end
|
103
|
+
|
104
|
+
test "returns nil if no translations are found (unsaved record)" do
|
105
|
+
post = Post.new(:subject => 'foo')
|
106
|
+
assert_equal 'foo', post.subject
|
107
|
+
assert_nil post.content
|
108
|
+
end
|
109
|
+
|
110
|
+
test "returns nil if no translations are found (saved record)" do
|
111
|
+
post = Post.create(:subject => 'foo')
|
112
|
+
post.reload
|
113
|
+
assert_equal 'foo', post.subject
|
114
|
+
assert_nil post.content
|
115
|
+
end
|
116
|
+
|
117
|
+
test "finds a German post" do
|
118
|
+
post = Post.create(:subject => 'foo (en)', :content => 'bar')
|
119
|
+
I18n.locale = :de
|
120
|
+
post = Post.first
|
121
|
+
post.subject = 'baz (de)'
|
122
|
+
post.save
|
123
|
+
assert_equal 'baz (de)', Post.first.subject
|
124
|
+
I18n.locale = :en
|
125
|
+
assert_equal 'foo (en)', Post.first.subject
|
126
|
+
end
|
127
|
+
|
128
|
+
test "saves an English post and loads correctly" do
|
129
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
130
|
+
assert post.save
|
131
|
+
post = Post.first
|
132
|
+
assert_equal 'foo', post.subject
|
133
|
+
assert_equal 'bar', post.content
|
134
|
+
end
|
135
|
+
|
136
|
+
test "returns the value for the correct locale, after locale switching" do
|
137
|
+
post = Post.create(:subject => 'foo')
|
138
|
+
I18n.locale = :de
|
139
|
+
post.subject = 'bar'
|
140
|
+
post.save
|
141
|
+
I18n.locale = :en
|
142
|
+
post = Post.first
|
143
|
+
assert_equal 'foo', post.subject
|
144
|
+
I18n.locale = :de
|
145
|
+
assert_equal 'bar', post.subject
|
146
|
+
end
|
147
|
+
|
148
|
+
test "returns the value for the correct locale, after locale switching, without saving" do
|
149
|
+
post = Post.create :subject => 'foo'
|
150
|
+
I18n.locale = :de
|
151
|
+
post.subject = 'bar'
|
152
|
+
I18n.locale = :en
|
153
|
+
assert_equal 'foo', post.subject
|
154
|
+
I18n.locale = :de
|
155
|
+
assert_equal 'bar', post.subject
|
156
|
+
end
|
157
|
+
|
158
|
+
test "saves all locales, even after locale switching" do
|
159
|
+
post = Post.new :subject => 'foo'
|
160
|
+
I18n.locale = :de
|
161
|
+
post.subject = 'bar'
|
162
|
+
I18n.locale = :he
|
163
|
+
post.subject = 'baz'
|
164
|
+
post.save
|
165
|
+
I18n.locale = :en
|
166
|
+
post = Post.first
|
167
|
+
assert_equal 'foo', post.subject
|
168
|
+
I18n.locale = :de
|
169
|
+
assert_equal 'bar', post.subject
|
170
|
+
I18n.locale = :he
|
171
|
+
assert_equal 'baz', post.subject
|
172
|
+
end
|
173
|
+
|
174
|
+
test "works with associations" do
|
175
|
+
blog = Blog.create
|
176
|
+
post1 = blog.posts.create(:subject => 'foo')
|
177
|
+
|
178
|
+
I18n.locale = :de
|
179
|
+
post2 = blog.posts.create(:subject => 'bar')
|
180
|
+
assert_equal 2, blog.posts.size
|
181
|
+
|
182
|
+
I18n.locale = :en
|
183
|
+
assert_equal 'foo', blog.posts.first.subject
|
184
|
+
assert_nil blog.posts.last.subject
|
185
|
+
|
186
|
+
I18n.locale = :de
|
187
|
+
assert_equal 'bar', blog.posts.last.subject
|
188
|
+
end
|
189
|
+
|
190
|
+
test "works with simple dynamic finders" do
|
191
|
+
foo = Post.create(:subject => 'foo')
|
192
|
+
Post.create(:subject => 'bar')
|
193
|
+
post = Post.find_by_subject('foo')
|
194
|
+
assert_equal foo, post
|
195
|
+
end
|
196
|
+
|
197
|
+
test 'change attribute on globalized model' do
|
198
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
199
|
+
assert_equal [], post.changed
|
200
|
+
post.subject = 'baz'
|
201
|
+
assert_equal ['subject'], post.changed
|
202
|
+
post.content = 'quux'
|
203
|
+
assert_member 'subject', post.changed
|
204
|
+
assert_member 'content', post.changed
|
205
|
+
end
|
206
|
+
|
207
|
+
test 'change attribute on globalized model after locale switching' do
|
208
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
209
|
+
assert_equal [], post.changed
|
210
|
+
post.subject = 'baz'
|
211
|
+
I18n.locale = :de
|
212
|
+
assert_equal ['subject'], post.changed
|
213
|
+
end
|
214
|
+
|
215
|
+
test 'complex writing and stashing' do
|
216
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
217
|
+
post.subject = nil
|
218
|
+
assert_nil post.subject
|
219
|
+
assert !post.valid?
|
220
|
+
post.subject = 'stashed_foo'
|
221
|
+
assert_equal 'stashed_foo', post.subject
|
222
|
+
end
|
223
|
+
|
224
|
+
test 'translated class locale setting' do
|
225
|
+
assert ActiveRecord::Base.respond_to?(:locale)
|
226
|
+
assert_equal :en, I18n.locale
|
227
|
+
assert_nil ActiveRecord::Base.locale
|
228
|
+
|
229
|
+
I18n.locale = :de
|
230
|
+
assert_equal :de, I18n.locale
|
231
|
+
assert_nil ActiveRecord::Base.locale
|
232
|
+
|
233
|
+
ActiveRecord::Base.locale = :es
|
234
|
+
assert_equal :de, I18n.locale
|
235
|
+
assert_equal :es, ActiveRecord::Base.locale
|
236
|
+
|
237
|
+
I18n.locale = :fr
|
238
|
+
assert_equal :fr, I18n.locale
|
239
|
+
assert_equal :es, ActiveRecord::Base.locale
|
240
|
+
end
|
241
|
+
|
242
|
+
test "untranslated class responds to locale" do
|
243
|
+
assert Blog.respond_to?(:locale)
|
244
|
+
end
|
245
|
+
|
246
|
+
test "to ensure locales in different classes are the same" do
|
247
|
+
ActiveRecord::Base.locale = :de
|
248
|
+
assert_equal :de, ActiveRecord::Base.locale
|
249
|
+
assert_equal :de, Parent.locale
|
250
|
+
|
251
|
+
Parent.locale = :es
|
252
|
+
assert_equal :es, ActiveRecord::Base.locale
|
253
|
+
assert_equal :es, Parent.locale
|
254
|
+
end
|
255
|
+
|
256
|
+
test "attribute saving goes by content locale and not global locale" do
|
257
|
+
ActiveRecord::Base.locale = :de
|
258
|
+
assert_equal :en, I18n.locale
|
259
|
+
Post.create :subject => 'foo'
|
260
|
+
assert_equal :de, Post.first.translations.first.locale
|
261
|
+
end
|
262
|
+
|
263
|
+
test "attribute loading goes by content locale and not global locale" do
|
264
|
+
post = Post.create(:subject => 'foo')
|
265
|
+
assert_nil ActiveRecord::Base.locale
|
266
|
+
|
267
|
+
ActiveRecord::Base.locale = :de
|
268
|
+
assert_equal :en, I18n.locale
|
269
|
+
post.update_attribute(:subject, 'foo [de]')
|
270
|
+
assert_equal 'foo [de]', Post.first.subject
|
271
|
+
|
272
|
+
ActiveRecord::Base.locale = :en
|
273
|
+
assert_equal 'foo', Post.first.subject
|
274
|
+
end
|
275
|
+
|
276
|
+
test "access content locale before setting" do
|
277
|
+
Globalize::ActiveRecord::ActMacro.class_eval "remove_class_variable(:@@locale)"
|
278
|
+
assert_nothing_raised { ActiveRecord::Base.locale }
|
279
|
+
end
|
280
|
+
|
281
|
+
test "available_locales" do
|
282
|
+
Post.locale = :de
|
283
|
+
post = Post.create(:subject => 'foo')
|
284
|
+
Post.locale = :es
|
285
|
+
post.update_attribute(:subject, 'bar')
|
286
|
+
Post.locale = :fr
|
287
|
+
post.update_attribute(:subject, 'baz')
|
288
|
+
assert_equal [:de, :es, :fr], post.available_locales
|
289
|
+
assert_equal [:de, :es, :fr], Post.first.available_locales
|
290
|
+
end
|
291
|
+
|
292
|
+
test "saving record correctly after post-save reload" do
|
293
|
+
reloader = Reloader.create(:content => 'foo')
|
294
|
+
assert_equal 'foo', reloader.content
|
295
|
+
end
|
296
|
+
|
297
|
+
test "including translations" do
|
298
|
+
I18n.locale = :de
|
299
|
+
Post.create(:subject => "Foo1", :content => "Bar1")
|
300
|
+
Post.create(:subject => "Foo2", :content => "Bar2")
|
301
|
+
|
302
|
+
class << Post
|
303
|
+
def translations_included
|
304
|
+
self.all(:include => :translations)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
default = Post.all.map { |x| [x.subject, x.content] }
|
309
|
+
with_include = Post.translations_included.map { |x| [x.subject, x.content] }
|
310
|
+
assert_equal default, with_include
|
311
|
+
end
|
312
|
+
|
313
|
+
test "setting multiple translations at once with options hash" do
|
314
|
+
Post.locale = :de
|
315
|
+
post = Post.create(:subject => "foo1", :content => "foo1")
|
316
|
+
Post.locale = :en
|
317
|
+
post.update_attributes(:subject => "bar1", :content => "bar1")
|
318
|
+
|
319
|
+
options = { :de => {:subject => "foo2", :content => "foo2"},
|
320
|
+
:en => {:subject => "bar2", :content => "bar2"} }
|
321
|
+
post.set_translations options
|
322
|
+
post.reload
|
323
|
+
|
324
|
+
assert ["bar2", "bar2"], [post.subject, post.content]
|
325
|
+
Post.locale = :de
|
326
|
+
assert ["foo2", "foo2"], [post.subject, post.content]
|
327
|
+
end
|
328
|
+
|
329
|
+
test "setting only one translation with set_translations" do
|
330
|
+
Post.locale = :de
|
331
|
+
post = Post.create(:subject => "foo1", :content => "foo1")
|
332
|
+
Post.locale = :en
|
333
|
+
post.update_attributes(:subject => "bar1", :content => "bar1")
|
334
|
+
|
335
|
+
options = { :en => { :subject => "bar2", :content => "bar2" } }
|
336
|
+
post.set_translations options
|
337
|
+
post.reload
|
338
|
+
|
339
|
+
assert ["bar2", "bar2"], [post.subject, post.content]
|
340
|
+
Post.locale = :de
|
341
|
+
assert ["foo1", "foo1"], [post.subject, post.content]
|
342
|
+
end
|
343
|
+
|
344
|
+
test "setting only selected attributes with set_translations" do
|
345
|
+
Post.locale = :de
|
346
|
+
post = Post.create(:subject => "foo1", :content => "foo1")
|
347
|
+
Post.locale = :en
|
348
|
+
post.update_attributes(:subject => "bar1", :content => "bar1")
|
349
|
+
|
350
|
+
options = { :de => { :content => "foo2" }, :en => { :subject => "bar2" } }
|
351
|
+
post.set_translations options
|
352
|
+
post.reload
|
353
|
+
|
354
|
+
assert ["bar2", "bar1"], [post.subject, post.content]
|
355
|
+
Post.locale = :de
|
356
|
+
assert ["foo1", "foo2"], [post.subject, post.content]
|
357
|
+
end
|
358
|
+
|
359
|
+
test "setting invalid attributes raises ArgumentError" do
|
360
|
+
Post.locale = :de
|
361
|
+
post = Post.create(:subject => "foo1", :content => "foo1")
|
362
|
+
Post.locale = :en
|
363
|
+
post.update_attributes(:subject => "bar1", :content => "bar1")
|
364
|
+
|
365
|
+
options = { :de => {:fake => "foo2"} }
|
366
|
+
exception = assert_raise(ActiveRecord::UnknownAttributeError) do
|
367
|
+
post.set_translations options
|
368
|
+
end
|
369
|
+
assert_equal "unknown attribute: fake", exception.message
|
370
|
+
end
|
371
|
+
|
372
|
+
test "reload accepting find options" do
|
373
|
+
p = Post.create(:subject => "Foo", :content => "Bar")
|
374
|
+
assert p.reload(:readonly => true, :lock => true)
|
375
|
+
assert_raise(ArgumentError) { p.reload(:foo => :bar) }
|
376
|
+
end
|
377
|
+
|
378
|
+
test "dependent destroy of translation" do
|
379
|
+
p = Post.create(:subject => "Foo", :content => "Bar")
|
380
|
+
assert_equal 1, PostTranslation.count
|
381
|
+
p.destroy
|
382
|
+
assert_equal 0, PostTranslation.count
|
383
|
+
end
|
384
|
+
|
385
|
+
test "translating subclass of untranslated comment model" do
|
386
|
+
translated_comment = TranslatedComment.create(:post => @post)
|
387
|
+
assert_nothing_raised { translated_comment.translations }
|
388
|
+
end
|
389
|
+
|
390
|
+
test "modifiying translated comments works as expected" do
|
391
|
+
I18n.locale = :en
|
392
|
+
translated_comment = TranslatedComment.create(:post => @post, :content => 'foo')
|
393
|
+
assert_equal 'foo', translated_comment.content
|
394
|
+
|
395
|
+
I18n.locale = :de
|
396
|
+
translated_comment.content = 'bar'
|
397
|
+
assert translated_comment.save
|
398
|
+
assert_equal 'bar', translated_comment.content
|
399
|
+
|
400
|
+
I18n.locale = :en
|
401
|
+
assert_equal 'foo', translated_comment.content
|
402
|
+
|
403
|
+
assert_equal 2, translated_comment.translations.size
|
404
|
+
end
|
405
|
+
|
406
|
+
test "can create a proxy class for a namespaced model" do
|
407
|
+
assert_nothing_raised do
|
408
|
+
module Foo
|
409
|
+
module Bar
|
410
|
+
class Baz < ActiveRecord::Base
|
411
|
+
translates :bumm
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
test "attribute translated before type cast" do
|
419
|
+
Post.locale = :en
|
420
|
+
post = Post.create(:subject => 'foo', :content => 'bar')
|
421
|
+
Post.locale = :de
|
422
|
+
post.update_attribute(:subject, "German foo")
|
423
|
+
assert_equal 'German foo', post.subject_before_type_cast
|
424
|
+
Post.locale = :en
|
425
|
+
assert_equal 'foo', post.subject_before_type_cast
|
426
|
+
end
|
427
|
+
|
428
|
+
test "don't override existing translation class" do
|
429
|
+
assert PostTranslation.new.respond_to?(:existing_method)
|
430
|
+
end
|
431
|
+
|
432
|
+
test "has_many and named scopes work with globalize" do
|
433
|
+
blog = Blog.create
|
434
|
+
assert_nothing_raised { blog.posts.foobar }
|
435
|
+
end
|
436
|
+
|
437
|
+
test "required_attribuets don't include non-translated attributes" do
|
438
|
+
validations = [
|
439
|
+
stub(:name => :name, :macro => :validates_presence_of),
|
440
|
+
stub(:name => :email, :macro => :validates_presence_of)
|
441
|
+
]
|
442
|
+
User.expects(:reflect_on_all_validations => validations)
|
443
|
+
assert_equal [:name], User.required_attributes
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
# TODO error checking for fields that exist in main table, don't exist in
|
448
|
+
# proxy table, aren't strings or text
|
449
|
+
#
|
450
|
+
# TODO allow finding by translated attributes in conditions?
|
451
|
+
# TODO generate advanced dynamic finders?
|