i18n 0.2.1 → 0.3.0

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

Potentially problematic release.


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

Files changed (77) hide show
  1. data/README.textile +44 -9
  2. data/Rakefile +2 -1
  3. data/VERSION +1 -1
  4. data/lib/i18n.rb +60 -15
  5. data/lib/i18n/backend.rb +14 -0
  6. data/lib/i18n/backend/active_record.rb +69 -0
  7. data/lib/i18n/backend/active_record/store_procs.rb +37 -0
  8. data/lib/i18n/backend/active_record/translation.rb +82 -0
  9. data/lib/i18n/backend/active_record_missing.rb +55 -0
  10. data/lib/i18n/backend/base.rb +235 -0
  11. data/lib/i18n/backend/cache.rb +71 -0
  12. data/lib/i18n/backend/chain.rb +74 -0
  13. data/lib/i18n/backend/fallbacks.rb +51 -0
  14. data/lib/i18n/backend/gettext.rb +75 -0
  15. data/lib/i18n/backend/helpers.rb +53 -0
  16. data/lib/i18n/backend/metadata.rb +73 -0
  17. data/lib/i18n/backend/pluralization.rb +57 -0
  18. data/lib/i18n/backend/simple.rb +15 -227
  19. data/lib/i18n/core_ext/object/meta_class.rb +5 -0
  20. data/lib/i18n/{string.rb → core_ext/string/interpolate.rb} +2 -0
  21. data/lib/i18n/exceptions.rb +2 -0
  22. data/lib/i18n/gettext.rb +25 -0
  23. data/lib/i18n/helpers.rb +5 -0
  24. data/lib/i18n/helpers/gettext.rb +64 -0
  25. data/lib/i18n/locale.rb +6 -0
  26. data/lib/i18n/locale/fallbacks.rb +98 -0
  27. data/lib/i18n/locale/tag.rb +28 -0
  28. data/lib/i18n/locale/tag/parents.rb +24 -0
  29. data/lib/i18n/locale/tag/rfc4646.rb +76 -0
  30. data/lib/i18n/locale/tag/simple.rb +41 -0
  31. data/test/all.rb +7 -2
  32. data/test/api/basics.rb +3 -1
  33. data/test/api/interpolation.rb +35 -4
  34. data/test/api/lambda.rb +5 -3
  35. data/test/api/link.rb +4 -2
  36. data/test/api/localization/date.rb +2 -0
  37. data/test/api/localization/date_time.rb +3 -1
  38. data/test/api/localization/lambda.rb +4 -2
  39. data/test/api/localization/time.rb +3 -1
  40. data/test/api/pluralization.rb +12 -15
  41. data/test/api/translation.rb +5 -3
  42. data/test/backend/active_record/active_record_test.rb +40 -0
  43. data/test/backend/active_record/all.rb +3 -0
  44. data/test/backend/active_record/api_test.rb +54 -0
  45. data/test/backend/active_record/setup.rb +166 -0
  46. data/test/backend/active_record_missing/active_record_missing_test.rb +63 -0
  47. data/test/backend/all/api_test.rb +88 -0
  48. data/test/backend/cache/cache_test.rb +69 -0
  49. data/test/backend/chain/api_test.rb +80 -0
  50. data/test/backend/chain/chain_test.rb +64 -0
  51. data/test/backend/fallbacks/api_test.rb +84 -0
  52. data/test/backend/fallbacks/fallbacks_test.rb +57 -0
  53. data/test/backend/metadata/metadata_test.rb +65 -0
  54. data/test/backend/pluralization/api_test.rb +86 -0
  55. data/test/backend/pluralization/pluralization_test.rb +43 -0
  56. data/test/backend/simple/all.rb +2 -0
  57. data/test/backend/simple/api_test.rb +27 -20
  58. data/test/backend/simple/helpers_test.rb +26 -0
  59. data/test/backend/simple/lookup_test.rb +2 -1
  60. data/test/backend/simple/{setup/localization.rb → setup.rb} +29 -11
  61. data/test/backend/simple/translations_test.rb +1 -6
  62. data/test/{string_test.rb → core_ext/string/interpolate_test.rb} +4 -2
  63. data/test/fixtures/locales/de.po +67 -0
  64. data/test/fixtures/locales/en.rb +2 -0
  65. data/test/fixtures/locales/plurals.rb +113 -0
  66. data/test/gettext/api_test.rb +204 -0
  67. data/test/gettext/backend_test.rb +84 -0
  68. data/test/i18n_exceptions_test.rb +3 -1
  69. data/test/i18n_load_path_test.rb +8 -1
  70. data/test/i18n_test.rb +30 -7
  71. data/test/locale/fallbacks_test.rb +128 -0
  72. data/test/locale/tag/rfc4646_test.rb +145 -0
  73. data/test/locale/tag/simple_test.rb +35 -0
  74. data/test/test_helper.rb +11 -5
  75. data/test/with_options.rb +2 -0
  76. metadata +75 -11
  77. data/test/backend/simple/setup/base.rb +0 -21
@@ -0,0 +1,88 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/chain'
5
+
6
+ module AllSetup
7
+ class Backend
8
+ include I18n::Backend::Base
9
+ include I18n::Backend::Cache
10
+ include I18n::Backend::Metadata
11
+ include I18n::Backend::Fallbacks
12
+ include I18n::Backend::Pluralization
13
+ end
14
+
15
+ def setup
16
+ super
17
+ I18n.backend = I18n::Backend::Chain.new(Backend.new, I18n.backend)
18
+ end
19
+
20
+ def test_using_all_features_backend
21
+ assert_equal Backend, I18n.backend.backends.first.class
22
+ end
23
+ end
24
+
25
+ class I18nAllBackendApiBasicsTest < Test::Unit::TestCase
26
+ include AllSetup
27
+ include Tests::Backend::Api::Basics
28
+ end
29
+
30
+ class I18nAllBackendApiTranslateTest < Test::Unit::TestCase
31
+ include Tests::Backend::Simple::Setup::Base
32
+ include AllSetup
33
+ include Tests::Backend::Api::Translation
34
+ end
35
+
36
+ class I18nAllBackendApiInterpolateTest < Test::Unit::TestCase
37
+ include Tests::Backend::Simple::Setup::Base
38
+ include AllSetup
39
+ include Tests::Backend::Api::Interpolation
40
+ end
41
+
42
+ class I18nAllBackendApiLambdaTest < Test::Unit::TestCase
43
+ include Tests::Backend::Simple::Setup::Base
44
+ include AllSetup
45
+ include Tests::Backend::Api::Lambda
46
+ end
47
+
48
+ class I18nAllBackendApiTranslateLinkedTest < Test::Unit::TestCase
49
+ include Tests::Backend::Simple::Setup::Base
50
+ include AllSetup
51
+ include Tests::Backend::Api::Link
52
+ end
53
+
54
+ class I18nAllBackendApiPluralizationTest < Test::Unit::TestCase
55
+ include Tests::Backend::Simple::Setup::Base
56
+ include AllSetup
57
+ include Tests::Backend::Api::Pluralization
58
+ end
59
+
60
+ class I18nAllBackendApiLocalizeDateTest < Test::Unit::TestCase
61
+ include Tests::Backend::Simple::Setup::Base
62
+ include Tests::Backend::Simple::Setup::Localization
63
+ include AllSetup
64
+ include Tests::Backend::Api::Localization::Date
65
+ end
66
+
67
+ class I18nAllBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
68
+ include Tests::Backend::Simple::Setup::Base
69
+ include Tests::Backend::Simple::Setup::Localization
70
+ include AllSetup
71
+ include Tests::Backend::Api::Localization::DateTime
72
+ end
73
+
74
+ class I18nAllBackendApiLocalizeTimeTest < Test::Unit::TestCase
75
+ include Tests::Backend::Simple::Setup::Base
76
+ include Tests::Backend::Simple::Setup::Localization
77
+ include AllSetup
78
+ include Tests::Backend::Api::Localization::Time
79
+ end
80
+
81
+ class I18nAllBackendApiLocalizeLambdaTest < Test::Unit::TestCase
82
+ include Tests::Backend::Simple::Setup::Base
83
+ include Tests::Backend::Simple::Setup::Localization
84
+ include AllSetup
85
+ include Tests::Backend::Api::Localization::Lambda
86
+ end
87
+
88
+
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/cache'
5
+
6
+ begin
7
+ require 'active_support/cache'
8
+ rescue LoadError
9
+ $stderr.puts "Skipping cache tests using ActiveSupport::Cache"
10
+ else
11
+
12
+ class I18nCacheBackendTest < Test::Unit::TestCase
13
+ class Backend
14
+ include I18n::Backend::Base
15
+ include I18n::Backend::Cache
16
+ end
17
+
18
+ def setup
19
+ I18n.backend = Backend.new
20
+ super
21
+ I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
22
+ end
23
+
24
+ def teardown
25
+ I18n.cache_store = nil
26
+ end
27
+
28
+ def test_uses_cache
29
+ assert I18n.cache_store.is_a?(ActiveSupport::Cache::MemoryStore)
30
+ end
31
+
32
+ define_method :"test translate hits the backend and caches the response" do
33
+ I18n.backend.expects(:lookup).returns('Foo')
34
+ assert_equal 'Foo', I18n.t(:foo)
35
+
36
+ I18n.backend.expects(:lookup).never
37
+ assert_equal 'Foo', I18n.t(:foo)
38
+
39
+ I18n.backend.expects(:lookup).returns('Bar')
40
+ assert_equal 'Bar', I18n.t(:bar)
41
+ end
42
+
43
+ define_method :"test still raises MissingTranslationData but also caches it" do
44
+ I18n.backend.expects(:lookup).returns(nil)
45
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
46
+ I18n.backend.expects(:lookup).never
47
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
48
+ end
49
+
50
+ define_method :"test uses 'i18n' as a cache key namespace by default" do
51
+ assert_equal 0, I18n.backend.send(:cache_key, :foo).index('i18n')
52
+ end
53
+
54
+ define_method :"test adds a custom cache key namespace" do
55
+ with_cache_namespace('bar') do
56
+ assert_equal 0, I18n.backend.send(:cache_key, :foo).index('i18n-bar')
57
+ end
58
+ end
59
+
60
+ protected
61
+
62
+ def with_cache_namespace(namespace)
63
+ I18n.cache_namespace = namespace
64
+ yield
65
+ I18n.cache_namespace = nil
66
+ end
67
+ end
68
+
69
+ end # AS cache check
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/chain'
5
+
6
+ module ChainSetup
7
+ def setup
8
+ super
9
+ first = I18n::Backend::Simple.new
10
+ I18n.backend = I18n::Backend::Chain.new(first, I18n.backend)
11
+ end
12
+
13
+ def test_using_chain_backend
14
+ assert_equal I18n::Backend::Chain, I18n.backend.class
15
+ end
16
+ end
17
+
18
+ class I18nChainBackendApiBasicsTest < Test::Unit::TestCase
19
+ include ChainSetup
20
+ include Tests::Backend::Api::Basics
21
+ end
22
+
23
+ class I18nChainBackendApiTranslateTest < Test::Unit::TestCase
24
+ include Tests::Backend::Simple::Setup::Base
25
+ include ChainSetup
26
+ include Tests::Backend::Api::Translation
27
+ end
28
+
29
+ class I18nChainBackendApiInterpolateTest < Test::Unit::TestCase
30
+ include Tests::Backend::Simple::Setup::Base
31
+ include ChainSetup
32
+ include Tests::Backend::Api::Interpolation
33
+ end
34
+
35
+ class I18nChainBackendApiLambdaTest < Test::Unit::TestCase
36
+ include Tests::Backend::Simple::Setup::Base
37
+ include ChainSetup
38
+ include Tests::Backend::Api::Lambda
39
+ end
40
+
41
+ class I18nChainBackendApiTranslateLinkedTest < Test::Unit::TestCase
42
+ include Tests::Backend::Simple::Setup::Base
43
+ include ChainSetup
44
+ include Tests::Backend::Api::Link
45
+ end
46
+
47
+ class I18nChainBackendApiPluralizationTest < Test::Unit::TestCase
48
+ include Tests::Backend::Simple::Setup::Base
49
+ include ChainSetup
50
+ include Tests::Backend::Api::Pluralization
51
+ end
52
+
53
+ class I18nChainBackendApiLocalizeDateTest < Test::Unit::TestCase
54
+ include Tests::Backend::Simple::Setup::Base
55
+ include Tests::Backend::Simple::Setup::Localization
56
+ include ChainSetup
57
+ include Tests::Backend::Api::Localization::Date
58
+ end
59
+
60
+ class I18nChainBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
61
+ include Tests::Backend::Simple::Setup::Base
62
+ include Tests::Backend::Simple::Setup::Localization
63
+ include ChainSetup
64
+ include Tests::Backend::Api::Localization::DateTime
65
+ end
66
+
67
+ class I18nChainBackendApiLocalizeTimeTest < Test::Unit::TestCase
68
+ include Tests::Backend::Simple::Setup::Base
69
+ include Tests::Backend::Simple::Setup::Localization
70
+ include ChainSetup
71
+ include Tests::Backend::Api::Localization::Time
72
+ end
73
+
74
+ class I18nChainBackendApiLocalizeLambdaTest < Test::Unit::TestCase
75
+ include Tests::Backend::Simple::Setup::Base
76
+ include Tests::Backend::Simple::Setup::Localization
77
+ include ChainSetup
78
+ include Tests::Backend::Api::Localization::Lambda
79
+ end
80
+
@@ -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 I18nChainBackendTest < 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,84 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+ require 'i18n/backend/fallbacks'
5
+
6
+ module FallbacksSetup
7
+ class Backend
8
+ include I18n::Backend::Base
9
+ include I18n::Backend::Fallbacks
10
+ end
11
+
12
+ def setup
13
+ I18n.backend = Backend.new
14
+ super
15
+ end
16
+
17
+ def test_uses_fallbacks
18
+ assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
19
+ end
20
+ end
21
+
22
+ class I18nFallbacksBackendApiBasicsTest < Test::Unit::TestCase
23
+ include FallbacksSetup
24
+ include Tests::Backend::Api::Basics
25
+ end
26
+
27
+ class I18nFallbacksBackendApiTranslateTest < Test::Unit::TestCase
28
+ include Tests::Backend::Simple::Setup::Base
29
+ include FallbacksSetup
30
+ include Tests::Backend::Api::Translation
31
+ end
32
+
33
+ class I18nFallbacksBackendApiInterpolateTest < Test::Unit::TestCase
34
+ include Tests::Backend::Simple::Setup::Base
35
+ include FallbacksSetup
36
+ include Tests::Backend::Api::Interpolation
37
+ end
38
+
39
+ class I18nFallbacksBackendApiLambdaTest < Test::Unit::TestCase
40
+ include Tests::Backend::Simple::Setup::Base
41
+ include FallbacksSetup
42
+ include Tests::Backend::Api::Lambda
43
+ end
44
+
45
+ class I18nFallbacksBackendApiTranslateLinkedTest < Test::Unit::TestCase
46
+ include Tests::Backend::Simple::Setup::Base
47
+ include FallbacksSetup
48
+ include Tests::Backend::Api::Link
49
+ end
50
+
51
+ class I18nFallbacksBackendApiPluralizationTest < Test::Unit::TestCase
52
+ include Tests::Backend::Simple::Setup::Base
53
+ include FallbacksSetup
54
+ include Tests::Backend::Api::Pluralization
55
+ end
56
+
57
+ class I18nFallbacksBackendApiLocalizeDateTest < Test::Unit::TestCase
58
+ include Tests::Backend::Simple::Setup::Base
59
+ include Tests::Backend::Simple::Setup::Localization
60
+ include FallbacksSetup
61
+ include Tests::Backend::Api::Localization::Date
62
+ end
63
+
64
+ class I18nFallbacksBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
65
+ include Tests::Backend::Simple::Setup::Base
66
+ include Tests::Backend::Simple::Setup::Localization
67
+ include FallbacksSetup
68
+ include Tests::Backend::Api::Localization::DateTime
69
+ end
70
+
71
+ class I18nFallbacksBackendApiLocalizeTimeTest < Test::Unit::TestCase
72
+ include Tests::Backend::Simple::Setup::Base
73
+ include Tests::Backend::Simple::Setup::Localization
74
+ include FallbacksSetup
75
+ include Tests::Backend::Api::Localization::Time
76
+ end
77
+
78
+ class I18nFallbacksBackendApiLocalizeLambdaTest < Test::Unit::TestCase
79
+ include Tests::Backend::Simple::Setup::Base
80
+ include Tests::Backend::Simple::Setup::Localization
81
+ include FallbacksSetup
82
+ include Tests::Backend::Api::Localization::Lambda
83
+ end
84
+
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
4
+
5
+ class I18nFallbacksBackendTest < 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
+ backend_store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :buz => 'Buz in :en')
14
+ backend_store_translations(:de, :bar => 'Bar in :de', :baz => 'Baz in :de')
15
+ backend_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 I18nChainWithFallbacksBackendTest < 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