activesupport 2.3.5 → 2.3.6.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (121) hide show
  1. data/CHANGELOG +23 -0
  2. data/lib/active_support.rb +1 -0
  3. data/lib/active_support/core_ext/date_time/conversions.rb +14 -3
  4. data/lib/active_support/core_ext/enumerable.rb +6 -0
  5. data/lib/active_support/core_ext/file/atomic.rb +2 -1
  6. data/lib/active_support/core_ext/numeric/conversions.rb +2 -2
  7. data/lib/active_support/core_ext/object.rb +1 -0
  8. data/lib/active_support/core_ext/object/metaclass.rb +6 -5
  9. data/lib/active_support/core_ext/object/singleton_class.rb +13 -0
  10. data/lib/active_support/core_ext/string.rb +0 -1
  11. data/lib/active_support/core_ext/string/output_safety.rb +148 -44
  12. data/lib/active_support/core_ext/time/calculations.rb +1 -1
  13. data/lib/active_support/inflector.rb +1 -1
  14. data/lib/active_support/json/backends/yajl.rb +40 -0
  15. data/lib/active_support/json/decoding.rb +16 -1
  16. data/lib/active_support/json/encoding.rb +11 -2
  17. data/lib/active_support/ordered_hash.rb +24 -1
  18. data/lib/active_support/vendor.rb +10 -2
  19. data/lib/active_support/vendor/i18n-0.3.3/CHANGELOG.textile +76 -0
  20. data/lib/active_support/vendor/{i18n-0.1.3 → i18n-0.3.3}/MIT-LICENSE +0 -0
  21. data/lib/active_support/vendor/i18n-0.3.3/README.textile +81 -0
  22. data/lib/active_support/vendor/i18n-0.3.3/Rakefile +24 -0
  23. data/lib/active_support/vendor/i18n-0.3.3/benchmark/example.yml +144 -0
  24. data/lib/active_support/vendor/i18n-0.3.3/benchmark/run.rb +71 -0
  25. data/lib/active_support/vendor/i18n-0.3.3/contributors.txt +17 -0
  26. data/lib/active_support/vendor/i18n-0.3.3/i18n.gemspec +165 -0
  27. data/lib/active_support/vendor/i18n-0.3.3/init.rb +1 -0
  28. data/lib/active_support/vendor/{i18n-0.1.3 → i18n-0.3.3}/lib/i18n.rb +99 -21
  29. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend.rb +17 -0
  30. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record.rb +70 -0
  31. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record/missing.rb +67 -0
  32. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record/store_procs.rb +38 -0
  33. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record/translation.rb +83 -0
  34. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/base.rb +259 -0
  35. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/cache.rb +75 -0
  36. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/cascade.rb +44 -0
  37. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/chain.rb +74 -0
  38. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/fallbacks.rb +52 -0
  39. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/fast.rb +68 -0
  40. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/gettext.rb +75 -0
  41. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/helpers.rb +80 -0
  42. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/interpolation_compiler.rb +119 -0
  43. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/metadata.rb +73 -0
  44. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/pluralization.rb +57 -0
  45. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/simple.rb +22 -0
  46. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/core_ext/object/meta_class.rb +5 -0
  47. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/core_ext/string/interpolate.rb +99 -0
  48. data/lib/active_support/vendor/{i18n-0.1.3 → i18n-0.3.3}/lib/i18n/exceptions.rb +14 -6
  49. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/gettext.rb +25 -0
  50. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/helpers.rb +5 -0
  51. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/helpers/gettext.rb +64 -0
  52. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale.rb +6 -0
  53. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/fallbacks.rb +98 -0
  54. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag.rb +28 -0
  55. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag/parents.rb +24 -0
  56. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag/rfc4646.rb +76 -0
  57. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag/simple.rb +41 -0
  58. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/version.rb +3 -0
  59. data/lib/active_support/vendor/i18n-0.3.3/test/all.rb +8 -0
  60. data/lib/active_support/vendor/i18n-0.3.3/test/api/basics.rb +15 -0
  61. data/lib/active_support/vendor/i18n-0.3.3/test/api/defaults.rb +40 -0
  62. data/lib/active_support/vendor/i18n-0.3.3/test/api/interpolation.rb +92 -0
  63. data/lib/active_support/vendor/i18n-0.3.3/test/api/link.rb +55 -0
  64. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/date.rb +91 -0
  65. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/date_time.rb +90 -0
  66. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/procs.rb +54 -0
  67. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/time.rb +84 -0
  68. data/lib/active_support/vendor/i18n-0.3.3/test/api/lookup.rb +45 -0
  69. data/lib/active_support/vendor/i18n-0.3.3/test/api/pluralization.rb +35 -0
  70. data/lib/active_support/vendor/i18n-0.3.3/test/api/procs.rb +40 -0
  71. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/active_record_test.rb +29 -0
  72. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/all_features_test.rb +40 -0
  73. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/cascade_test.rb +31 -0
  74. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/chain_test.rb +26 -0
  75. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/fallbacks_test.rb +33 -0
  76. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/fast_test.rb +31 -0
  77. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/pluralization_test.rb +33 -0
  78. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/simple_test.rb +21 -0
  79. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/active_record/missing_test.rb +60 -0
  80. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/active_record_test.rb +52 -0
  81. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/cache_test.rb +72 -0
  82. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/cascade_test.rb +66 -0
  83. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/chain_test.rb +64 -0
  84. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/fallbacks_test.rb +57 -0
  85. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/fast_test.rb +50 -0
  86. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/helpers_test.rb +26 -0
  87. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/interpolation_compiler_test.rb +107 -0
  88. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/metadata_test.rb +67 -0
  89. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/pluralization_test.rb +43 -0
  90. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/simple_test.rb +77 -0
  91. data/lib/active_support/vendor/i18n-0.3.3/test/cases/core_ext/string/interpolate_test.rb +94 -0
  92. data/lib/active_support/vendor/i18n-0.3.3/test/cases/gettext/api_test.rb +201 -0
  93. data/lib/active_support/vendor/i18n-0.3.3/test/cases/gettext/backend_test.rb +91 -0
  94. data/lib/active_support/vendor/{i18n-0.1.3/test → i18n-0.3.3/test/cases}/i18n_exceptions_test.rb +8 -10
  95. data/lib/active_support/vendor/i18n-0.3.3/test/cases/i18n_load_path_test.rb +23 -0
  96. data/lib/active_support/vendor/i18n-0.3.3/test/cases/i18n_test.rb +172 -0
  97. data/lib/active_support/vendor/i18n-0.3.3/test/cases/locale/fallbacks_test.rb +126 -0
  98. data/lib/active_support/vendor/i18n-0.3.3/test/cases/locale/tag/rfc4646_test.rb +143 -0
  99. data/lib/active_support/vendor/i18n-0.3.3/test/cases/locale/tag/simple_test.rb +33 -0
  100. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/de.po +72 -0
  101. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/en.rb +3 -0
  102. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/en.yml +3 -0
  103. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/plurals.rb +113 -0
  104. data/lib/active_support/vendor/i18n-0.3.3/test/test_helper.rb +100 -0
  105. data/lib/active_support/vendor/i18n-0.3.3/vendor/po_parser.rb +329 -0
  106. data/lib/active_support/version.rb +1 -1
  107. data/lib/active_support/whiny_nil.rb +1 -1
  108. data/lib/active_support/xml_mini/libxml.rb +23 -83
  109. data/lib/active_support/xml_mini/libxmlsax.rb +74 -0
  110. data/lib/active_support/xml_mini/nokogiri.rb +25 -22
  111. data/lib/active_support/xml_mini/nokogirisax.rb +73 -0
  112. metadata +108 -20
  113. data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
  114. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
  115. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
  116. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -214
  117. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
  118. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
  119. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
  120. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
  121. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+
5
+ class I18nBackendCascadeTest < Test::Unit::TestCase
6
+ class Backend
7
+ include I18n::Backend::Base
8
+ include I18n::Backend::Cascade
9
+ end
10
+
11
+ def setup
12
+ I18n.backend = Backend.new
13
+ store_translations(:en,
14
+ :foo => 'foo',
15
+ :bar => { :baz => 'baz' }
16
+ )
17
+ end
18
+
19
+ define_method "test: still returns an existing translation as usual" do
20
+ assert_equal 'foo', I18n.t(:foo)
21
+ assert_equal 'baz', I18n.t(:'bar.baz')
22
+ end
23
+
24
+ define_method "test: falls back by cutting keys off the end of the scope" do
25
+ assert_equal 'foo', I18n.t(:'does_not_exist.foo')
26
+ assert_equal 'foo', I18n.t(:'does_not_exist.does_not_exist.foo')
27
+
28
+ assert_equal 'baz', I18n.t(:'bar.does_not_exist.baz')
29
+ assert_equal 'baz', I18n.t(:'bar.does_not_exist.does_not_exist.baz')
30
+ end
31
+
32
+ define_method "test: raises I18n::MissingTranslationData exception when no translation was found" do
33
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:'foo.does_not_exist', :raise => true) }
34
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:'bar.baz.does_not_exist', :raise => true) }
35
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:'does_not_exist.bar.baz', :raise => true) }
36
+ end
37
+
38
+ define_method "test: cascades before evaluating the default" do
39
+ assert_equal 'foo', I18n.t(:foo, :scope => :does_not_exist, :default => 'default')
40
+ end
41
+
42
+ define_method "test: let's us assemble required fallbacks for ActiveRecord validation messages" do
43
+ store_translations(:en,
44
+ :errors => {
45
+ :reply => {
46
+ :title => {
47
+ :blank => 'blank on reply title'
48
+ },
49
+ :taken => 'taken on reply'
50
+ },
51
+ :topic => {
52
+ :title => {
53
+ :format => 'format on topic title'
54
+ },
55
+ :length => 'length on topic'
56
+ },
57
+ :odd => 'odd on errors'
58
+ }
59
+ )
60
+ assert_equal 'blank on reply title', I18n.t(:'errors.reply.title.blank', :default => :'errors.topic.title.blank')
61
+ assert_equal 'taken on reply', I18n.t(:'errors.reply.title.taken', :default => :'errors.topic.title.taken')
62
+ assert_equal 'format on topic title', I18n.t(:'errors.reply.title.format', :default => :'errors.topic.title.format')
63
+ assert_equal 'length on topic', I18n.t(:'errors.reply.title.length', :default => :'errors.topic.title.length')
64
+ assert_equal 'odd on errors', I18n.t(:'errors.reply.title.odd', :default => :'errors.topic.title.odd')
65
+ end
66
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/chain'
5
+
6
+ class I18nBackendChainTest < Test::Unit::TestCase
7
+ def setup
8
+ @first = backend(:en => {
9
+ :foo => 'Foo', :formats => { :short => 'short' }, :plural_1 => { :one => '{{count}}' }
10
+ })
11
+ @second = backend(:en => {
12
+ :bar => 'Bar', :formats => { :long => 'long' }, :plural_2 => { :one => 'one' }
13
+ })
14
+ @chain = I18n.backend = I18n::Backend::Chain.new(@first, @second)
15
+ end
16
+
17
+ define_method "test: looks up translations from the first chained backend" do
18
+ assert_equal 'Foo', @first.send(:translations)[:en][:foo]
19
+ assert_equal 'Foo', I18n.t(:foo)
20
+ end
21
+
22
+ define_method "test: looks up translations from the second chained backend" do
23
+ assert_equal 'Bar', @second.send(:translations)[:en][:bar]
24
+ assert_equal 'Bar', I18n.t(:bar)
25
+ end
26
+
27
+ define_method "test: defaults only apply to lookups on the last backend in the chain" do
28
+ assert_equal 'Foo', I18n.t(:foo, :default => 'Bah')
29
+ assert_equal 'Bar', I18n.t(:bar, :default => 'Bah')
30
+ assert_equal 'Bah', I18n.t(:bah, :default => 'Bah') # default kicks in only here
31
+ end
32
+
33
+ define_method "test: default" do
34
+ assert_equal 'Fuh', I18n.t(:default => 'Fuh')
35
+ assert_equal 'Zero', I18n.t(:default => { :zero => 'Zero' }, :count => 0)
36
+ assert_equal({ :zero => 'Zero' }, I18n.t(:default => { :zero => 'Zero' }))
37
+ assert_equal 'Foo', I18n.t(:default => :foo)
38
+ end
39
+
40
+ define_method "test: namespace lookup collects results from all backends" do
41
+ assert_equal({ :short => 'short', :long => 'long' }, I18n.t(:formats))
42
+ end
43
+
44
+ define_method "test: namespace lookup with only the first backend returning a result" do
45
+ assert_equal({ :one => '{{count}}' }, I18n.t(:plural_1))
46
+ end
47
+
48
+ define_method "test: pluralization still works" do
49
+ assert_equal '1', I18n.t(:plural_1, :count => 1)
50
+ assert_equal 'one', I18n.t(:plural_2, :count => 1)
51
+ end
52
+
53
+ define_method "test: bulk lookup collects results from all backends" do
54
+ assert_equal ['Foo', 'Bar'], I18n.t([:foo, :bar])
55
+ end
56
+
57
+ protected
58
+
59
+ def backend(translations)
60
+ backend = I18n::Backend::Simple.new
61
+ translations.each { |locale, translations| backend.store_translations(locale, translations) }
62
+ backend
63
+ end
64
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+
5
+ class I18nBackendFallbacksTest < Test::Unit::TestCase
6
+ class Backend
7
+ include I18n::Backend::Base
8
+ include I18n::Backend::Fallbacks
9
+ end
10
+
11
+ def setup
12
+ I18n.backend = Backend.new
13
+ store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :buz => 'Buz in :en')
14
+ store_translations(:de, :bar => 'Bar in :de', :baz => 'Baz in :de')
15
+ store_translations(:'de-DE', :baz => 'Baz in :de-DE')
16
+ end
17
+
18
+ define_method "test: still returns an existing translation as usual" do
19
+ assert_equal 'Foo in :en', I18n.t(:foo, :locale => :en)
20
+ assert_equal 'Bar in :de', I18n.t(:bar, :locale => :de)
21
+ assert_equal 'Baz in :de-DE', I18n.t(:baz, :locale => :'de-DE')
22
+ end
23
+
24
+ define_method "test: returns the :en translation for a missing :de translation" do
25
+ assert_equal 'Foo in :en', I18n.t(:foo, :locale => :de)
26
+ end
27
+
28
+ define_method "test: returns the :de translation for a missing :'de-DE' translation" do
29
+ assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE')
30
+ end
31
+
32
+ define_method "test: returns the :en translation for translation missing in both :de and :'de-De'" do
33
+ assert_equal 'Buz in :en', I18n.t(:buz, :locale => :'de-DE')
34
+ end
35
+
36
+ define_method "test: raises I18n::MissingTranslationData exception when no translation was found" do
37
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:faa, :locale => :en, :raise => true) }
38
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:faa, :locale => :de, :raise => true) }
39
+ end
40
+ end
41
+
42
+ class I18nBackendFallbacksWithChainTest < Test::Unit::TestCase
43
+ class Backend
44
+ include I18n::Backend::Base
45
+ include I18n::Backend::Fallbacks
46
+ end
47
+
48
+ def setup
49
+ backend = Backend.new
50
+ backend.store_translations(:de, :foo => 'FOO')
51
+ I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, backend)
52
+ end
53
+
54
+ define_method "test: falls back from de-DE to de when there is no translation for de-DE available" do
55
+ assert_equal 'FOO', I18n.t(:foo, :locale => :'de-DE')
56
+ end
57
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require File.expand_path(File.dirname(__FILE__) + '/simple_test')
5
+
6
+ class I18nBackendFastTest < I18nBackendSimpleTest
7
+ class FastBackend
8
+ include I18n::Backend::Base
9
+ include I18n::Backend::Fast
10
+ end
11
+
12
+ def setup
13
+ super
14
+ I18n.backend = FastBackend.new
15
+ end
16
+ end
17
+
18
+ class I18nBackendFastSpecificTest < Test::Unit::TestCase
19
+ class FastBackend
20
+ include I18n::Backend::Base
21
+ include I18n::Backend::Fast
22
+ end
23
+
24
+ def setup
25
+ @backend = FastBackend.new
26
+ end
27
+
28
+ def assert_flattens(expected, nested)
29
+ assert_equal expected, @backend.send(:flatten_hash, nested)
30
+ end
31
+
32
+ def test_hash_flattening_works
33
+ assert_flattens(
34
+ {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"},
35
+ {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}}
36
+ )
37
+ assert_flattens({:a=>{:b =>['a', 'b']}, :"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}})
38
+ end
39
+
40
+ def test_pluralization_logic_and_lookup_works
41
+ counts_hash = {:zero => 'zero', :one => 'one', :other => 'other'}
42
+ @backend.store_translations :en, {:a => counts_hash}
43
+ assert_equal 'one', @backend.translate(:en, :a, :count => 1)
44
+ end
45
+
46
+ def test_translation_subtree_retrieval
47
+ @backend.store_translations :en, :a => {:foo => 'bar'}
48
+ assert_equal({:foo => 'bar'}, @backend.translate(:en, :a))
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
3
+
4
+ class I18nBackendHelpersTest < Test::Unit::TestCase
5
+ def setup
6
+ @backend = I18n::Backend::Simple.new
7
+ end
8
+
9
+ def test_wind_keys
10
+ hash = { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}
11
+ expected = { :"a.b.c" => "d", :"a.b.e" => "f", :"a.g" => "h", :"i" => "j" }
12
+ assert_equal expected, @backend.wind_keys(hash)
13
+ end
14
+
15
+ def test_unwind_keys
16
+ hash = { "a.b.c" => "d", :"a.b.e" => "f", :"a.g" => "h", "i" => "j" }
17
+ expected = { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}
18
+ assert_equal expected, @backend.unwind_keys(hash)
19
+ end
20
+
21
+ def test_deep_symbolize_keys
22
+ result = @backend.deep_symbolize_keys('foo' => { 'bar' => { 'baz' => 'bar' } })
23
+ expected = {:foo => {:bar => {:baz => 'bar'}}}
24
+ assert_equal expected, result
25
+ end
26
+ end
@@ -0,0 +1,107 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+
5
+ class InterpolationCompilerTest < Test::Unit::TestCase
6
+ Compiler = I18n::Backend::InterpolationCompiler::Compiler
7
+
8
+ def compile_and_interpolate(str, values = {})
9
+ Compiler.compile_if_an_interpolation(str).i18n_interpolate(values)
10
+ end
11
+
12
+ def assert_escapes_interpolation_key(expected, malicious_str)
13
+ assert_equal(expected, Compiler.send(:escape_key_sym, malicious_str))
14
+ end
15
+
16
+ def test_escape_key_properly_escapes
17
+ assert_escapes_interpolation_key ':"\""', '"'
18
+ assert_escapes_interpolation_key ':"\\\\"', '\\'
19
+ assert_escapes_interpolation_key ':"\\\\\""', '\\"'
20
+ assert_escapes_interpolation_key ':"\#{}"', '#{}'
21
+ assert_escapes_interpolation_key ':"\\\\\#{}"', '\#{}'
22
+ end
23
+
24
+ def assert_escapes_plain_string(expected, plain_str)
25
+ assert_equal expected, Compiler.send(:escape_plain_str, plain_str)
26
+ end
27
+
28
+ def test_escape_plain_string_properly_escapes
29
+ assert_escapes_plain_string '\\"', '"'
30
+ assert_escapes_plain_string '\'', '\''
31
+ assert_escapes_plain_string '\\#', '#'
32
+ assert_escapes_plain_string '\\#{}', '#{}'
33
+ assert_escapes_plain_string '\\\\\\"','\\"'
34
+ end
35
+
36
+ def test_non_interpolated_strings_or_arrays_dont_get_compiled
37
+ ['abc', '\\{a}}', '{a}}', []].each do |obj|
38
+ Compiler.compile_if_an_interpolation(obj)
39
+ assert_equal false, obj.respond_to?(:i18n_interpolate)
40
+ end
41
+ end
42
+
43
+ def test_interpolated_string_gets_compiled
44
+ assert_equal '-A-', compile_and_interpolate('-{{a}}-', :a => 'A')
45
+ end
46
+
47
+ def assert_handles_key(str, key)
48
+ assert_equal 'A', compile_and_interpolate(str, key => 'A')
49
+ end
50
+
51
+ def test_compiles_fancy_keys
52
+ assert_handles_key('{{\}}', :'\\' )
53
+ assert_handles_key('{{#}}', :'#' )
54
+ assert_handles_key('{{#{}}', :'#{' )
55
+ assert_handles_key('{{#$SAFE}}', :'#$SAFE')
56
+ assert_handles_key('{{\000}}', :'\000' )
57
+ assert_handles_key('{{\'}}', :'\'' )
58
+ assert_handles_key('{{\'\'}}', :'\'\'' )
59
+ assert_handles_key('{{a.b}}', :'a.b' )
60
+ assert_handles_key('{{ }}', :' ' )
61
+ assert_handles_key('{{:}}', :':' )
62
+ assert_handles_key("{{:''}}", :":''" )
63
+ assert_handles_key('{{:"}}', :':"' )
64
+ end
65
+
66
+ def test_str_containing_only_escaped_interpolation_is_handled_correctly
67
+ assert_equal 'abc {{x}}', compile_and_interpolate('abc \\{{x}}')
68
+ end
69
+
70
+ def test_handles_weired_strings
71
+ assert_equal '#{} a', compile_and_interpolate('#{} {{a}}', :a => 'a')
72
+ assert_equal '"#{abc}"', compile_and_interpolate('"#{ab{{a}}c}"', :a => '' )
73
+ assert_equal 'a}', compile_and_interpolate('{{{a}}}', :'{a' => 'a')
74
+ assert_equal '"', compile_and_interpolate('"{{a}}', :a => '' )
75
+ assert_equal 'a{{a}}', compile_and_interpolate('{{a}}\\{{a}}', :a => 'a')
76
+ assert_equal '\\{{a}}', compile_and_interpolate('\\\\{{a}}')
77
+ assert_equal '\";eval("a")', compile_and_interpolate('\";eval("{{a}}")', :a => 'a')
78
+ assert_equal '\";eval("a")', compile_and_interpolate('\";eval("a"){{a}}',:a => '' )
79
+ assert_equal "\na", compile_and_interpolate("\n{{a}}", :a => 'a')
80
+ end
81
+ end
82
+
83
+ class I18nBackendInterpolationCompilerTest < Test::Unit::TestCase
84
+ class Backend
85
+ include I18n::Backend::Base
86
+ include I18n::Backend::InterpolationCompiler
87
+ end
88
+
89
+ include Tests::Api::Interpolation
90
+
91
+ def setup
92
+ I18n.backend = Backend.new
93
+ super
94
+ end
95
+
96
+ # pre-compile default strings to make sure we are testing I18n::Backend::InterpolationCompiler
97
+ def interpolate(*args)
98
+ options = args.last.kind_of?(Hash) ? args.last : {}
99
+ if default_str = options[:default]
100
+ I18n::Backend::InterpolationCompiler::Compiler.compile_if_an_interpolation(default_str)
101
+ end
102
+ super
103
+ end
104
+
105
+ # I kinda don't think this really is a correct behavior
106
+ undef :'test interpolation: given no values it does not alter the string'
107
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/metadata'
5
+
6
+ class I18nBackendMetadataTest < Test::Unit::TestCase
7
+ class Backend
8
+ include I18n::Backend::Base
9
+ include I18n::Backend::Metadata
10
+ end
11
+
12
+ def setup
13
+ I18n.backend = Backend.new
14
+ store_translations(:en, :foo => 'Hi {{name}}')
15
+ end
16
+
17
+ define_method "test: translation strings carry metadata" do
18
+ translation = I18n.t(:foo)
19
+ assert translation.respond_to?(:translation_metadata)
20
+ assert translation.translation_metadata.is_a?(Hash)
21
+ end
22
+
23
+ define_method "test: translate preserves metadata stored on original Strings" do
24
+ store_metadata(:foo, :bar, 'bar')
25
+ assert_equal 'bar', I18n.t(:foo).translation_metadata[:bar]
26
+ end
27
+
28
+ define_method "test: translate preserves metadata stored on original Strings (when interpolated)" do
29
+ store_metadata(:foo, :bar, 'bar')
30
+ assert_equal 'bar', I18n.t(:foo, :name => 'David').translation_metadata[:bar]
31
+ end
32
+
33
+ define_method "test: translate adds the locale to metadata on Strings" do
34
+ assert_equal :en, I18n.t(:foo, :locale => :en).translation_metadata[:locale]
35
+ end
36
+
37
+ define_method "test: translate adds the key to metadata on Strings" do
38
+ assert_equal :foo, I18n.t(:foo).translation_metadata[:key]
39
+ end
40
+
41
+ define_method "test: translate adds the default to metadata on Strings" do
42
+ assert_equal 'bar', I18n.t(:foo, :default => 'bar', :name => '').translation_metadata[:default]
43
+ end
44
+
45
+ define_method "test: translation adds the interpolation values to metadata on Strings" do
46
+ assert_equal({:name => 'David'}, I18n.t(:foo, :name => 'David').translation_metadata[:values])
47
+ end
48
+
49
+ define_method "test: interpolation adds the original string to metadata on Strings" do
50
+ assert_equal('Hi {{name}}', I18n.t(:foo, :name => 'David').translation_metadata[:original])
51
+ end
52
+
53
+ define_method "test: pluralizatoin adds the count to metadata on Strings" do
54
+ assert_equal(1, I18n.t(:missing, :count => 1, :default => { :one => 'foo' }).translation_metadata[:count])
55
+ end
56
+
57
+ protected
58
+
59
+ def translations
60
+ I18n.backend.instance_variable_get(:@translations)
61
+ end
62
+
63
+ def store_metadata(key, name, value)
64
+ translations[:en][key].translation_metadata[name] = value
65
+ end
66
+ end
67
+
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/pluralization'
5
+
6
+ class I18nBackendPluralizationTest < Test::Unit::TestCase
7
+ class Backend
8
+ include I18n::Backend::Base
9
+ include I18n::Backend::Pluralization
10
+ end
11
+
12
+ def setup
13
+ I18n.backend = Backend.new
14
+ @rule = lambda { |n| n == 1 ? :one : n == 0 || (2..10).include?(n % 100) ? :few : (11..19).include?(n % 100) ? :many : :other }
15
+ store_translations(:foo, :i18n => { :plural => { :rule => @rule } })
16
+ @entry = { :zero => 'zero', :one => 'one', :few => 'few', :many => 'many', :other => 'other' }
17
+ end
18
+
19
+ define_method "test: pluralization picks a pluralizer from :'i18n.pluralize'" do
20
+ assert_equal @rule, I18n.backend.send(:pluralizer, :foo)
21
+ end
22
+
23
+ define_method "test: pluralization picks :one for 1" do
24
+ assert_equal 'one', I18n.t(:count => 1, :default => @entry, :locale => :foo)
25
+ end
26
+
27
+ define_method "test: pluralization picks :few for 2" do
28
+ assert_equal 'few', I18n.t(:count => 2, :default => @entry, :locale => :foo)
29
+ end
30
+
31
+ define_method "test: pluralization picks :many for 11" do
32
+ assert_equal 'many', I18n.t(:count => 11, :default => @entry, :locale => :foo)
33
+ end
34
+
35
+ define_method "test: pluralization picks zero for 0 if the key is contained in the data" do
36
+ assert_equal 'zero', I18n.t(:count => 0, :default => @entry, :locale => :foo)
37
+ end
38
+
39
+ define_method "test: pluralization picks few for 0 if the key is not contained in the data" do
40
+ @entry.delete(:zero)
41
+ assert_equal 'few', I18n.t(:count => 0, :default => @entry, :locale => :foo)
42
+ end
43
+ end