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.
Files changed (52) hide show
  1. data/.gitignore +2 -1
  2. data/README.textile +27 -143
  3. data/VERSION +1 -1
  4. data/generators/templates/db_backend_migration.rb +3 -3
  5. data/globalize2.gemspec +30 -49
  6. data/init.rb +1 -8
  7. data/lib/globalize.rb +15 -0
  8. data/lib/globalize/active_record.rb +195 -0
  9. data/lib/globalize/active_record/adapter.rb +80 -0
  10. data/lib/globalize/active_record/attributes.rb +25 -0
  11. data/lib/globalize/active_record/migration.rb +40 -0
  12. data/lib/{globalize/i18n → i18n}/missing_translations_log_handler.rb +8 -8
  13. data/lib/{globalize/i18n → i18n}/missing_translations_raise_handler.rb +3 -5
  14. data/test/active_record/fallbacks_test.rb +102 -0
  15. data/test/{model/active_record → active_record}/migration_test.rb +21 -26
  16. data/test/{model/active_record → active_record}/sti_translated_test.rb +4 -30
  17. data/test/active_record/translates_test.rb +87 -0
  18. data/test/active_record/translation_class_test.rb +30 -0
  19. data/test/active_record/validation_tests.rb +75 -0
  20. data/test/active_record_test.rb +451 -0
  21. data/test/data/models.rb +16 -0
  22. data/test/data/schema.rb +23 -7
  23. data/test/i18n/missing_translations_test.rb +6 -6
  24. data/test/test_helper.rb +55 -15
  25. metadata +33 -46
  26. data/lib/globalize/backend/chain.rb +0 -102
  27. data/lib/globalize/backend/pluralizing.rb +0 -37
  28. data/lib/globalize/backend/static.rb +0 -61
  29. data/lib/globalize/load_path.rb +0 -63
  30. data/lib/globalize/locale/fallbacks.rb +0 -63
  31. data/lib/globalize/locale/language_tag.rb +0 -81
  32. data/lib/globalize/model/active_record.rb +0 -56
  33. data/lib/globalize/model/active_record/adapter.rb +0 -100
  34. data/lib/globalize/model/active_record/translated.rb +0 -174
  35. data/lib/globalize/translation.rb +0 -32
  36. data/lib/locale/root.yml +0 -3
  37. data/lib/rails_edge_load_path_patch.rb +0 -40
  38. data/notes.textile +0 -51
  39. data/test/backends/chained_test.rb +0 -175
  40. data/test/backends/pluralizing_test.rb +0 -63
  41. data/test/backends/static_test.rb +0 -147
  42. data/test/data/locale/all.yml +0 -2
  43. data/test/data/locale/de-DE.yml +0 -2
  44. data/test/data/locale/en-US.yml +0 -2
  45. data/test/data/locale/en-US/module.yml +0 -2
  46. data/test/data/locale/fi-FI/module.yml +0 -2
  47. data/test/data/locale/root.yml +0 -0
  48. data/test/load_path_test.rb +0 -49
  49. data/test/locale/fallbacks_test.rb +0 -154
  50. data/test/locale/language_tag_test.rb +0 -130
  51. data/test/model/active_record/translated_test.rb +0 -487
  52. 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?