radiant-globalize2-extension 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (318) hide show
  1. data/Rakefile +136 -0
  2. data/app/views/admin/shared/_change_locale.html.haml +22 -0
  3. data/app/views/admin/shared/_change_locale_admin.html.haml +7 -0
  4. data/app/views/admin/shared/_globalize_td.html.haml +4 -0
  5. data/app/views/admin/shared/_globalize_th.html.haml +2 -0
  6. data/config/routes.rb +4 -0
  7. data/cucumber.yml +1 -0
  8. data/db/migrate/20090728084238_create_translation_tables.rb +23 -0
  9. data/db/migrate/20090728114627_populate_translations.rb +21 -0
  10. data/db/migrate/20090729085422_remove_translated_attributes.rb +16 -0
  11. data/features/globalize_layouts.feature +19 -0
  12. data/features/globalize_pages.feature +58 -0
  13. data/features/globalize_snippets.feature +19 -0
  14. data/features/step_definitions/admin_steps.rb +58 -0
  15. data/features/step_definitions/webrat_steps.rb +119 -0
  16. data/features/support/env.rb +30 -0
  17. data/features/support/paths.rb +26 -0
  18. data/globalize2_extension.rb +93 -0
  19. data/lib/globalize2/compatibility/archive/archive_page_extensions.rb +21 -0
  20. data/lib/globalize2/compatibility/copy_move/copy_move_model_extensions.rb +22 -0
  21. data/lib/globalize2/compatibility/paginate/globalize_tags.rb +19 -0
  22. data/lib/globalize2/compatibility/paginate/page_extensions.rb +9 -0
  23. data/lib/globalize2/compatibility/vhost/page_extensions.rb +9 -0
  24. data/lib/globalize2/form_builder_extensions.rb +21 -0
  25. data/lib/globalize2/globalize_tags.rb +203 -0
  26. data/lib/globalize2/globalized_fields_controller_extension.rb +22 -0
  27. data/lib/globalize2/page_extensions.rb +88 -0
  28. data/lib/globalize2/page_part_extensions.rb +21 -0
  29. data/lib/globalize2/pages_controller_extensions.rb +9 -0
  30. data/lib/globalize2/site_controller_extensions.rb +24 -0
  31. data/lib/tasks/globalize2_extension_tasks.rake +28 -0
  32. data/public/images/admin/ad.gif +0 -0
  33. data/public/images/admin/ae.gif +0 -0
  34. data/public/images/admin/af.gif +0 -0
  35. data/public/images/admin/ag.gif +0 -0
  36. data/public/images/admin/ai.gif +0 -0
  37. data/public/images/admin/al.gif +0 -0
  38. data/public/images/admin/am.gif +0 -0
  39. data/public/images/admin/an.gif +0 -0
  40. data/public/images/admin/ao.gif +0 -0
  41. data/public/images/admin/ar.gif +0 -0
  42. data/public/images/admin/as.gif +0 -0
  43. data/public/images/admin/at.gif +0 -0
  44. data/public/images/admin/au.gif +0 -0
  45. data/public/images/admin/aw.gif +0 -0
  46. data/public/images/admin/ax.gif +0 -0
  47. data/public/images/admin/az.gif +0 -0
  48. data/public/images/admin/ba.gif +0 -0
  49. data/public/images/admin/bb.gif +0 -0
  50. data/public/images/admin/bd.gif +0 -0
  51. data/public/images/admin/be.gif +0 -0
  52. data/public/images/admin/bf.gif +0 -0
  53. data/public/images/admin/bg.gif +0 -0
  54. data/public/images/admin/bh.gif +0 -0
  55. data/public/images/admin/bi.gif +0 -0
  56. data/public/images/admin/bj.gif +0 -0
  57. data/public/images/admin/bm.gif +0 -0
  58. data/public/images/admin/bn.gif +0 -0
  59. data/public/images/admin/bo.gif +0 -0
  60. data/public/images/admin/br.gif +0 -0
  61. data/public/images/admin/bs.gif +0 -0
  62. data/public/images/admin/bt.gif +0 -0
  63. data/public/images/admin/bv.gif +0 -0
  64. data/public/images/admin/bw.gif +0 -0
  65. data/public/images/admin/by.gif +0 -0
  66. data/public/images/admin/bz.gif +0 -0
  67. data/public/images/admin/ca.gif +0 -0
  68. data/public/images/admin/catalonia.gif +0 -0
  69. data/public/images/admin/cc.gif +0 -0
  70. data/public/images/admin/cd.gif +0 -0
  71. data/public/images/admin/cf.gif +0 -0
  72. data/public/images/admin/cg.gif +0 -0
  73. data/public/images/admin/ch.gif +0 -0
  74. data/public/images/admin/ci.gif +0 -0
  75. data/public/images/admin/ck.gif +0 -0
  76. data/public/images/admin/cl.gif +0 -0
  77. data/public/images/admin/cm.gif +0 -0
  78. data/public/images/admin/cn.gif +0 -0
  79. data/public/images/admin/co.gif +0 -0
  80. data/public/images/admin/cr.gif +0 -0
  81. data/public/images/admin/cs.gif +0 -0
  82. data/public/images/admin/cu.gif +0 -0
  83. data/public/images/admin/cv.gif +0 -0
  84. data/public/images/admin/cx.gif +0 -0
  85. data/public/images/admin/cy.gif +0 -0
  86. data/public/images/admin/cz.gif +0 -0
  87. data/public/images/admin/de.gif +0 -0
  88. data/public/images/admin/dj.gif +0 -0
  89. data/public/images/admin/dk.gif +0 -0
  90. data/public/images/admin/dm.gif +0 -0
  91. data/public/images/admin/do.gif +0 -0
  92. data/public/images/admin/dz.gif +0 -0
  93. data/public/images/admin/ec.gif +0 -0
  94. data/public/images/admin/ee.gif +0 -0
  95. data/public/images/admin/eg.gif +0 -0
  96. data/public/images/admin/eh.gif +0 -0
  97. data/public/images/admin/en.gif +0 -0
  98. data/public/images/admin/england.gif +0 -0
  99. data/public/images/admin/er.gif +0 -0
  100. data/public/images/admin/es.gif +0 -0
  101. data/public/images/admin/et.gif +0 -0
  102. data/public/images/admin/europeanunion.gif +0 -0
  103. data/public/images/admin/fam.gif +0 -0
  104. data/public/images/admin/fi.gif +0 -0
  105. data/public/images/admin/fj.gif +0 -0
  106. data/public/images/admin/fk.gif +0 -0
  107. data/public/images/admin/fm.gif +0 -0
  108. data/public/images/admin/fo.gif +0 -0
  109. data/public/images/admin/fr.gif +0 -0
  110. data/public/images/admin/ga.gif +0 -0
  111. data/public/images/admin/gb.gif +0 -0
  112. data/public/images/admin/gd.gif +0 -0
  113. data/public/images/admin/ge.gif +0 -0
  114. data/public/images/admin/gf.gif +0 -0
  115. data/public/images/admin/gh.gif +0 -0
  116. data/public/images/admin/gi.gif +0 -0
  117. data/public/images/admin/gl.gif +0 -0
  118. data/public/images/admin/gm.gif +0 -0
  119. data/public/images/admin/gn.gif +0 -0
  120. data/public/images/admin/gp.gif +0 -0
  121. data/public/images/admin/gq.gif +0 -0
  122. data/public/images/admin/gr.gif +0 -0
  123. data/public/images/admin/gs.gif +0 -0
  124. data/public/images/admin/gt.gif +0 -0
  125. data/public/images/admin/gu.gif +0 -0
  126. data/public/images/admin/gw.gif +0 -0
  127. data/public/images/admin/gy.gif +0 -0
  128. data/public/images/admin/hk.gif +0 -0
  129. data/public/images/admin/hm.gif +0 -0
  130. data/public/images/admin/hn.gif +0 -0
  131. data/public/images/admin/hr.gif +0 -0
  132. data/public/images/admin/ht.gif +0 -0
  133. data/public/images/admin/hu.gif +0 -0
  134. data/public/images/admin/id.gif +0 -0
  135. data/public/images/admin/ie.gif +0 -0
  136. data/public/images/admin/il.gif +0 -0
  137. data/public/images/admin/in.gif +0 -0
  138. data/public/images/admin/io.gif +0 -0
  139. data/public/images/admin/iq.gif +0 -0
  140. data/public/images/admin/ir.gif +0 -0
  141. data/public/images/admin/is.gif +0 -0
  142. data/public/images/admin/it.gif +0 -0
  143. data/public/images/admin/jm.gif +0 -0
  144. data/public/images/admin/jo.gif +0 -0
  145. data/public/images/admin/jp.gif +0 -0
  146. data/public/images/admin/ke.gif +0 -0
  147. data/public/images/admin/kg.gif +0 -0
  148. data/public/images/admin/kh.gif +0 -0
  149. data/public/images/admin/ki.gif +0 -0
  150. data/public/images/admin/km.gif +0 -0
  151. data/public/images/admin/kn.gif +0 -0
  152. data/public/images/admin/kp.gif +0 -0
  153. data/public/images/admin/kr.gif +0 -0
  154. data/public/images/admin/kw.gif +0 -0
  155. data/public/images/admin/ky.gif +0 -0
  156. data/public/images/admin/kz.gif +0 -0
  157. data/public/images/admin/la.gif +0 -0
  158. data/public/images/admin/lb.gif +0 -0
  159. data/public/images/admin/lc.gif +0 -0
  160. data/public/images/admin/li.gif +0 -0
  161. data/public/images/admin/lk.gif +0 -0
  162. data/public/images/admin/lr.gif +0 -0
  163. data/public/images/admin/ls.gif +0 -0
  164. data/public/images/admin/lt.gif +0 -0
  165. data/public/images/admin/lu.gif +0 -0
  166. data/public/images/admin/lv.gif +0 -0
  167. data/public/images/admin/ly.gif +0 -0
  168. data/public/images/admin/ma.gif +0 -0
  169. data/public/images/admin/mc.gif +0 -0
  170. data/public/images/admin/md.gif +0 -0
  171. data/public/images/admin/me.gif +0 -0
  172. data/public/images/admin/mg.gif +0 -0
  173. data/public/images/admin/mh.gif +0 -0
  174. data/public/images/admin/mk.gif +0 -0
  175. data/public/images/admin/ml.gif +0 -0
  176. data/public/images/admin/mm.gif +0 -0
  177. data/public/images/admin/mn.gif +0 -0
  178. data/public/images/admin/mo.gif +0 -0
  179. data/public/images/admin/mp.gif +0 -0
  180. data/public/images/admin/mq.gif +0 -0
  181. data/public/images/admin/mr.gif +0 -0
  182. data/public/images/admin/ms.gif +0 -0
  183. data/public/images/admin/mt.gif +0 -0
  184. data/public/images/admin/mu.gif +0 -0
  185. data/public/images/admin/mv.gif +0 -0
  186. data/public/images/admin/mw.gif +0 -0
  187. data/public/images/admin/mx.gif +0 -0
  188. data/public/images/admin/my.gif +0 -0
  189. data/public/images/admin/mz.gif +0 -0
  190. data/public/images/admin/na.gif +0 -0
  191. data/public/images/admin/nc.gif +0 -0
  192. data/public/images/admin/ne.gif +0 -0
  193. data/public/images/admin/nf.gif +0 -0
  194. data/public/images/admin/ng.gif +0 -0
  195. data/public/images/admin/ni.gif +0 -0
  196. data/public/images/admin/nl.gif +0 -0
  197. data/public/images/admin/no.gif +0 -0
  198. data/public/images/admin/np.gif +0 -0
  199. data/public/images/admin/nr.gif +0 -0
  200. data/public/images/admin/nu.gif +0 -0
  201. data/public/images/admin/nz.gif +0 -0
  202. data/public/images/admin/om.gif +0 -0
  203. data/public/images/admin/pa.gif +0 -0
  204. data/public/images/admin/pe.gif +0 -0
  205. data/public/images/admin/pf.gif +0 -0
  206. data/public/images/admin/pg.gif +0 -0
  207. data/public/images/admin/ph.gif +0 -0
  208. data/public/images/admin/pk.gif +0 -0
  209. data/public/images/admin/pl.gif +0 -0
  210. data/public/images/admin/pm.gif +0 -0
  211. data/public/images/admin/pn.gif +0 -0
  212. data/public/images/admin/pr.gif +0 -0
  213. data/public/images/admin/ps.gif +0 -0
  214. data/public/images/admin/pt.gif +0 -0
  215. data/public/images/admin/pw.gif +0 -0
  216. data/public/images/admin/py.gif +0 -0
  217. data/public/images/admin/qa.gif +0 -0
  218. data/public/images/admin/re.gif +0 -0
  219. data/public/images/admin/ro.gif +0 -0
  220. data/public/images/admin/rs.gif +0 -0
  221. data/public/images/admin/ru.gif +0 -0
  222. data/public/images/admin/rw.gif +0 -0
  223. data/public/images/admin/sa.gif +0 -0
  224. data/public/images/admin/sb.gif +0 -0
  225. data/public/images/admin/sc.gif +0 -0
  226. data/public/images/admin/scotland.gif +0 -0
  227. data/public/images/admin/sd.gif +0 -0
  228. data/public/images/admin/se.gif +0 -0
  229. data/public/images/admin/sg.gif +0 -0
  230. data/public/images/admin/sh.gif +0 -0
  231. data/public/images/admin/si.gif +0 -0
  232. data/public/images/admin/sj.gif +0 -0
  233. data/public/images/admin/sk.gif +0 -0
  234. data/public/images/admin/sl.gif +0 -0
  235. data/public/images/admin/sm.gif +0 -0
  236. data/public/images/admin/sn.gif +0 -0
  237. data/public/images/admin/so.gif +0 -0
  238. data/public/images/admin/sr.gif +0 -0
  239. data/public/images/admin/st.gif +0 -0
  240. data/public/images/admin/sv.gif +0 -0
  241. data/public/images/admin/sy.gif +0 -0
  242. data/public/images/admin/sz.gif +0 -0
  243. data/public/images/admin/tc.gif +0 -0
  244. data/public/images/admin/td.gif +0 -0
  245. data/public/images/admin/tf.gif +0 -0
  246. data/public/images/admin/tg.gif +0 -0
  247. data/public/images/admin/th.gif +0 -0
  248. data/public/images/admin/tj.gif +0 -0
  249. data/public/images/admin/tk.gif +0 -0
  250. data/public/images/admin/tl.gif +0 -0
  251. data/public/images/admin/tm.gif +0 -0
  252. data/public/images/admin/tn.gif +0 -0
  253. data/public/images/admin/to.gif +0 -0
  254. data/public/images/admin/tr.gif +0 -0
  255. data/public/images/admin/tt.gif +0 -0
  256. data/public/images/admin/tv.gif +0 -0
  257. data/public/images/admin/tw.gif +0 -0
  258. data/public/images/admin/tz.gif +0 -0
  259. data/public/images/admin/ua.gif +0 -0
  260. data/public/images/admin/ug.gif +0 -0
  261. data/public/images/admin/um.gif +0 -0
  262. data/public/images/admin/us.gif +0 -0
  263. data/public/images/admin/uy.gif +0 -0
  264. data/public/images/admin/uz.gif +0 -0
  265. data/public/images/admin/va.gif +0 -0
  266. data/public/images/admin/vc.gif +0 -0
  267. data/public/images/admin/ve.gif +0 -0
  268. data/public/images/admin/vg.gif +0 -0
  269. data/public/images/admin/vi.gif +0 -0
  270. data/public/images/admin/vn.gif +0 -0
  271. data/public/images/admin/vu.gif +0 -0
  272. data/public/images/admin/wales.gif +0 -0
  273. data/public/images/admin/wf.gif +0 -0
  274. data/public/images/admin/ws.gif +0 -0
  275. data/public/images/admin/ye.gif +0 -0
  276. data/public/images/admin/yt.gif +0 -0
  277. data/public/images/admin/za.gif +0 -0
  278. data/public/images/admin/zm.gif +0 -0
  279. data/public/images/admin/zw.gif +0 -0
  280. data/public/stylesheets/sass/admin/globalize2.sass +59 -0
  281. data/readme.md +159 -0
  282. data/spec/controllers/admin/pages_controller_spec.rb +22 -0
  283. data/spec/controllers/site_controller_spec.rb +40 -0
  284. data/spec/factories.rb +39 -0
  285. data/spec/models/globalize_tags_spec.rb +155 -0
  286. data/spec/models/page_spec.rb +91 -0
  287. data/spec/spec.opts +6 -0
  288. data/spec/spec_helper.rb +34 -0
  289. data/vendor/plugins/globalize2/.gitignore +5 -0
  290. data/vendor/plugins/globalize2/LICENSE +21 -0
  291. data/vendor/plugins/globalize2/README.textile +86 -0
  292. data/vendor/plugins/globalize2/Rakefile +39 -0
  293. data/vendor/plugins/globalize2/VERSION +1 -0
  294. data/vendor/plugins/globalize2/generators/db_backend.rb +0 -0
  295. data/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb +25 -0
  296. data/vendor/plugins/globalize2/globalize2.gemspec +81 -0
  297. data/vendor/plugins/globalize2/init.rb +1 -0
  298. data/vendor/plugins/globalize2/lib/globalize.rb +15 -0
  299. data/vendor/plugins/globalize2/lib/globalize/active_record.rb +215 -0
  300. data/vendor/plugins/globalize2/lib/globalize/active_record/adapter.rb +80 -0
  301. data/vendor/plugins/globalize2/lib/globalize/active_record/attributes.rb +25 -0
  302. data/vendor/plugins/globalize2/lib/globalize/active_record/migration.rb +44 -0
  303. data/vendor/plugins/globalize2/lib/i18n/missing_translations_log_handler.rb +41 -0
  304. data/vendor/plugins/globalize2/lib/i18n/missing_translations_raise_handler.rb +25 -0
  305. data/vendor/plugins/globalize2/test/active_record/fallbacks_test.rb +102 -0
  306. data/vendor/plugins/globalize2/test/active_record/migration_test.rb +118 -0
  307. data/vendor/plugins/globalize2/test/active_record/sti_translated_test.rb +61 -0
  308. data/vendor/plugins/globalize2/test/active_record/translates_test.rb +96 -0
  309. data/vendor/plugins/globalize2/test/active_record/translation_class_test.rb +30 -0
  310. data/vendor/plugins/globalize2/test/active_record/validation_tests.rb +75 -0
  311. data/vendor/plugins/globalize2/test/active_record_test.rb +467 -0
  312. data/vendor/plugins/globalize2/test/all.rb +2 -0
  313. data/vendor/plugins/globalize2/test/data/models.rb +62 -0
  314. data/vendor/plugins/globalize2/test/data/no_globalize_schema.rb +11 -0
  315. data/vendor/plugins/globalize2/test/data/schema.rb +55 -0
  316. data/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb +36 -0
  317. data/vendor/plugins/globalize2/test/test_helper.rb +76 -0
  318. metadata +409 -0
@@ -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,467 @@
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_not_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
+
446
+ test "attribute_names returns translated and regular attribute names" do
447
+ Post.create :subject => "foo", :content => "bar"
448
+ assert_equal Post.last.attribute_names.sort, %w[blog_id content id subject]
449
+ end
450
+
451
+ test "attributes returns translated and regular attributes" do
452
+ Post.create :subject => "foo", :content => "bar"
453
+ assert_equal Post.last.attributes.keys.sort, %w[blog_id content id subject]
454
+ end
455
+
456
+ test "to_xml includes translated fields" do
457
+ Post.create :subject => "foo", :content => "bar"
458
+ assert Post.last.to_xml =~ /subject/
459
+ assert Post.last.to_xml =~ /content/
460
+ end
461
+ end
462
+
463
+ # TODO error checking for fields that exist in main table, don't exist in
464
+ # proxy table, aren't strings or text
465
+ #
466
+ # TODO allow finding by translated attributes in conditions?
467
+ # TODO generate advanced dynamic finders?