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.
- data/README.textile +44 -9
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/lib/i18n.rb +60 -15
- data/lib/i18n/backend.rb +14 -0
- data/lib/i18n/backend/active_record.rb +69 -0
- data/lib/i18n/backend/active_record/store_procs.rb +37 -0
- data/lib/i18n/backend/active_record/translation.rb +82 -0
- data/lib/i18n/backend/active_record_missing.rb +55 -0
- data/lib/i18n/backend/base.rb +235 -0
- data/lib/i18n/backend/cache.rb +71 -0
- data/lib/i18n/backend/chain.rb +74 -0
- data/lib/i18n/backend/fallbacks.rb +51 -0
- data/lib/i18n/backend/gettext.rb +75 -0
- data/lib/i18n/backend/helpers.rb +53 -0
- data/lib/i18n/backend/metadata.rb +73 -0
- data/lib/i18n/backend/pluralization.rb +57 -0
- data/lib/i18n/backend/simple.rb +15 -227
- data/lib/i18n/core_ext/object/meta_class.rb +5 -0
- data/lib/i18n/{string.rb → core_ext/string/interpolate.rb} +2 -0
- data/lib/i18n/exceptions.rb +2 -0
- data/lib/i18n/gettext.rb +25 -0
- data/lib/i18n/helpers.rb +5 -0
- data/lib/i18n/helpers/gettext.rb +64 -0
- data/lib/i18n/locale.rb +6 -0
- data/lib/i18n/locale/fallbacks.rb +98 -0
- data/lib/i18n/locale/tag.rb +28 -0
- data/lib/i18n/locale/tag/parents.rb +24 -0
- data/lib/i18n/locale/tag/rfc4646.rb +76 -0
- data/lib/i18n/locale/tag/simple.rb +41 -0
- data/test/all.rb +7 -2
- data/test/api/basics.rb +3 -1
- data/test/api/interpolation.rb +35 -4
- data/test/api/lambda.rb +5 -3
- data/test/api/link.rb +4 -2
- data/test/api/localization/date.rb +2 -0
- data/test/api/localization/date_time.rb +3 -1
- data/test/api/localization/lambda.rb +4 -2
- data/test/api/localization/time.rb +3 -1
- data/test/api/pluralization.rb +12 -15
- data/test/api/translation.rb +5 -3
- data/test/backend/active_record/active_record_test.rb +40 -0
- data/test/backend/active_record/all.rb +3 -0
- data/test/backend/active_record/api_test.rb +54 -0
- data/test/backend/active_record/setup.rb +166 -0
- data/test/backend/active_record_missing/active_record_missing_test.rb +63 -0
- data/test/backend/all/api_test.rb +88 -0
- data/test/backend/cache/cache_test.rb +69 -0
- data/test/backend/chain/api_test.rb +80 -0
- data/test/backend/chain/chain_test.rb +64 -0
- data/test/backend/fallbacks/api_test.rb +84 -0
- data/test/backend/fallbacks/fallbacks_test.rb +57 -0
- data/test/backend/metadata/metadata_test.rb +65 -0
- data/test/backend/pluralization/api_test.rb +86 -0
- data/test/backend/pluralization/pluralization_test.rb +43 -0
- data/test/backend/simple/all.rb +2 -0
- data/test/backend/simple/api_test.rb +27 -20
- data/test/backend/simple/helpers_test.rb +26 -0
- data/test/backend/simple/lookup_test.rb +2 -1
- data/test/backend/simple/{setup/localization.rb → setup.rb} +29 -11
- data/test/backend/simple/translations_test.rb +1 -6
- data/test/{string_test.rb → core_ext/string/interpolate_test.rb} +4 -2
- data/test/fixtures/locales/de.po +67 -0
- data/test/fixtures/locales/en.rb +2 -0
- data/test/fixtures/locales/plurals.rb +113 -0
- data/test/gettext/api_test.rb +204 -0
- data/test/gettext/backend_test.rb +84 -0
- data/test/i18n_exceptions_test.rb +3 -1
- data/test/i18n_load_path_test.rb +8 -1
- data/test/i18n_test.rb +30 -7
- data/test/locale/fallbacks_test.rb +128 -0
- data/test/locale/tag/rfc4646_test.rb +145 -0
- data/test/locale/tag/simple_test.rb +35 -0
- data/test/test_helper.rb +11 -5
- data/test/with_options.rb +2 -0
- metadata +75 -11
- data/test/backend/simple/setup/base.rb +0 -21
data/lib/i18n/exceptions.rb
CHANGED
data/lib/i18n/gettext.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Gettext
|
5
|
+
PLURAL_SEPARATOR = "\001"
|
6
|
+
CONTEXT_SEPARATOR = "\004"
|
7
|
+
|
8
|
+
@@plural_keys = { :en => [:one, :other] }
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# returns an array of plural keys for the given locale so that we can
|
12
|
+
# convert from gettext's integer-index based style
|
13
|
+
# TODO move this information to the pluralization module
|
14
|
+
def plural_keys(locale)
|
15
|
+
@@plural_keys[locale] || @@plural_keys[:en]
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract_scope(msgid, separator)
|
19
|
+
scope = msgid.to_s.split(separator)
|
20
|
+
msgid = scope.pop
|
21
|
+
[scope, msgid]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/i18n/helpers.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Helpers
|
5
|
+
# Implements classical Gettext style accessors. To use this include the
|
6
|
+
# module to the global namespace or wherever you want to use it.
|
7
|
+
#
|
8
|
+
# include I18n::Helpers::Gettext
|
9
|
+
module Gettext
|
10
|
+
def gettext(msgid, options = {})
|
11
|
+
I18n.t(msgid, { :default => msgid, :separator => '|' }.merge(options))
|
12
|
+
end
|
13
|
+
alias _ gettext
|
14
|
+
|
15
|
+
def sgettext(msgid, separator = '|')
|
16
|
+
scope, msgid = I18n::Gettext.extract_scope(msgid, separator)
|
17
|
+
I18n.t(msgid, :scope => scope, :default => msgid)
|
18
|
+
end
|
19
|
+
alias s_ sgettext
|
20
|
+
|
21
|
+
def pgettext(msgctxt, msgid)
|
22
|
+
separator = I18n::Gettext::CONTEXT_SEPARATOR
|
23
|
+
sgettext([msgctxt, msgid].join(separator), separator)
|
24
|
+
end
|
25
|
+
alias p_ pgettext
|
26
|
+
|
27
|
+
def ngettext(msgid, msgid_plural, n = 1)
|
28
|
+
nsgettext(msgid, msgid_plural, n)
|
29
|
+
end
|
30
|
+
alias n_ ngettext
|
31
|
+
|
32
|
+
# Method signatures:
|
33
|
+
# nsgettext('Fruits|apple', 'apples', 2)
|
34
|
+
# nsgettext(['Fruits|apple', 'apples'], 2)
|
35
|
+
def nsgettext(msgid, msgid_plural, n = 1, separator = '|')
|
36
|
+
if msgid.is_a?(Array)
|
37
|
+
msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n
|
38
|
+
separator = '|' unless separator.is_a?(String)
|
39
|
+
end
|
40
|
+
|
41
|
+
scope, msgid = I18n::Gettext.extract_scope(msgid, separator)
|
42
|
+
default = { :one => msgid, :other => msgid_plural }
|
43
|
+
I18n.t(msgid, :default => default, :count => n, :scope => scope)
|
44
|
+
end
|
45
|
+
alias ns_ nsgettext
|
46
|
+
|
47
|
+
# Method signatures:
|
48
|
+
# npgettext('Fruits', 'apple', 'apples', 2)
|
49
|
+
# npgettext('Fruits', ['apple', 'apples'], 2)
|
50
|
+
def npgettext(msgctxt, msgid, msgid_plural, n = 1)
|
51
|
+
separator = I18n::Gettext::CONTEXT_SEPARATOR
|
52
|
+
|
53
|
+
if msgid.is_a?(Array)
|
54
|
+
msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural
|
55
|
+
else
|
56
|
+
msgid = [msgctxt, msgid].join(separator)
|
57
|
+
end
|
58
|
+
|
59
|
+
nsgettext(msgid, msgid_plural, n, separator)
|
60
|
+
end
|
61
|
+
alias np_ npgettext
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/i18n/locale.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Locale Fallbacks
|
4
|
+
#
|
5
|
+
# Extends the I18n module to hold a fallbacks instance which is set to an
|
6
|
+
# instance of I18n::Locale::Fallbacks by default but can be swapped with a
|
7
|
+
# different implementation.
|
8
|
+
#
|
9
|
+
# Locale fallbacks will compute a number of fallback locales for a given locale.
|
10
|
+
# For example:
|
11
|
+
#
|
12
|
+
# <pre><code>
|
13
|
+
# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] </code></pre>
|
14
|
+
#
|
15
|
+
# Locale fallbacks always fall back to
|
16
|
+
#
|
17
|
+
# * all parent locales of a given locale (e.g. :es for :"es-MX") first,
|
18
|
+
# * the current default locales and all of their parents second
|
19
|
+
#
|
20
|
+
# The default locales are set to [I18n.default_locale] by default but can be
|
21
|
+
# set to something else.
|
22
|
+
#
|
23
|
+
# One can additionally add any number of additional fallback locales manually.
|
24
|
+
# These will be added before the default locales to the fallback chain. For
|
25
|
+
# example:
|
26
|
+
#
|
27
|
+
# # using the default locale as default fallback locale
|
28
|
+
#
|
29
|
+
# I18n.default_locale = :"en-US"
|
30
|
+
# I18n.fallbacks = I18n::Fallbacks.new(:"de-AT" => :"de-DE")
|
31
|
+
# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en]
|
32
|
+
#
|
33
|
+
# # using a custom locale as default fallback locale
|
34
|
+
#
|
35
|
+
# I18n.fallbacks = I18n::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de)
|
36
|
+
# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en]
|
37
|
+
# I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en]
|
38
|
+
#
|
39
|
+
# # mapping fallbacks to an existing instance
|
40
|
+
#
|
41
|
+
# # people speaking Catalan also speak Spanish as spoken in Spain
|
42
|
+
# fallbacks = I18n.fallbacks
|
43
|
+
# fallbacks.map(:ca => :"es-ES")
|
44
|
+
# fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
|
45
|
+
#
|
46
|
+
# # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel
|
47
|
+
# fallbacks.map(:"ar-PS" => :"he-IL")
|
48
|
+
# fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
|
49
|
+
# fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
|
50
|
+
#
|
51
|
+
# # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland
|
52
|
+
# fallbacks.map(:sms => [:"se-FI", :"fi-FI"])
|
53
|
+
# fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
|
54
|
+
|
55
|
+
module I18n
|
56
|
+
module Locale
|
57
|
+
class Fallbacks < Hash
|
58
|
+
def initialize(*mappings)
|
59
|
+
@map = {}
|
60
|
+
map(mappings.pop) if mappings.last.is_a?(Hash)
|
61
|
+
self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings
|
62
|
+
end
|
63
|
+
|
64
|
+
def defaults=(defaults)
|
65
|
+
@defaults = defaults.map { |default| compute(default, false) }.flatten
|
66
|
+
end
|
67
|
+
attr_reader :defaults
|
68
|
+
|
69
|
+
def [](locale)
|
70
|
+
raise InvalidLocale.new(locale) if locale.nil?
|
71
|
+
locale = locale.to_sym
|
72
|
+
super || store(locale, compute(locale))
|
73
|
+
end
|
74
|
+
|
75
|
+
def map(mappings)
|
76
|
+
mappings.each do |from, to|
|
77
|
+
from, to = from.to_sym, Array(to)
|
78
|
+
to.each do |to|
|
79
|
+
@map[from] ||= []
|
80
|
+
@map[from] << to.to_sym
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
def compute(tags, include_defaults = true)
|
88
|
+
result = Array(tags).collect do |tag|
|
89
|
+
tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym }
|
90
|
+
tags.each { |tag| tags += compute(@map[tag]) if @map[tag] }
|
91
|
+
tags
|
92
|
+
end.flatten
|
93
|
+
result.push(*defaults) if include_defaults
|
94
|
+
result.uniq
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Locale
|
5
|
+
module Tag
|
6
|
+
autoload :Parents, 'i18n/locale/tag/parents'
|
7
|
+
autoload :Rfc4646, 'i18n/locale/tag/rfc4646'
|
8
|
+
autoload :Simple, 'i18n/locale/tag/simple'
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+.
|
12
|
+
def implementation
|
13
|
+
@@implementation ||= Simple
|
14
|
+
end
|
15
|
+
|
16
|
+
# Sets the current locale tag implementation. Use this to set a different locale tag implementation.
|
17
|
+
def implementation=(implementation)
|
18
|
+
@@implementation = implementation
|
19
|
+
end
|
20
|
+
|
21
|
+
# Factory method for locale tags. Delegates to the current locale tag implementation.
|
22
|
+
def tag(tag)
|
23
|
+
implementation.tag(tag)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
module Locale
|
5
|
+
module Tag
|
6
|
+
module Parents
|
7
|
+
def parent
|
8
|
+
@parent ||= begin
|
9
|
+
segs = to_a.compact
|
10
|
+
segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self_and_parents
|
15
|
+
@self_and_parents ||= [self] + parents
|
16
|
+
end
|
17
|
+
|
18
|
+
def parents
|
19
|
+
@parents ||= ([parent] + (parent ? parent.parents : [])).compact
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# RFC 4646/47 compliant Locale tag implementation that parses locale tags to
|
4
|
+
# subtags such as language, script, region, variant etc.
|
5
|
+
#
|
6
|
+
# For more information see by http://en.wikipedia.org/wiki/IETF_language_tag
|
7
|
+
#
|
8
|
+
# Rfc4646::Parser does not implement grandfathered tags.
|
9
|
+
|
10
|
+
module I18n
|
11
|
+
module Locale
|
12
|
+
module Tag
|
13
|
+
RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ]
|
14
|
+
RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase }
|
15
|
+
|
16
|
+
class Rfc4646 < Struct.new(*RFC4646_SUBTAGS)
|
17
|
+
class << self
|
18
|
+
# Parses the given tag and returns a Tag instance if it is valid.
|
19
|
+
# Returns false if the given tag is not valid according to RFC 4646.
|
20
|
+
def tag(tag)
|
21
|
+
matches = parser.match(tag)
|
22
|
+
new(*matches) if matches
|
23
|
+
end
|
24
|
+
|
25
|
+
def parser
|
26
|
+
@@parser ||= Rfc4646::Parser
|
27
|
+
end
|
28
|
+
|
29
|
+
def parser=(parser)
|
30
|
+
@@parser = parser
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
include Parents
|
35
|
+
|
36
|
+
RFC4646_FORMATS.each do |name, format|
|
37
|
+
define_method(name) { self[name].send(format) unless self[name].nil? }
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_sym
|
41
|
+
to_s.to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
@tag ||= to_a.compact.join("-")
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_a
|
49
|
+
members.collect { |attr| self.send(attr) }
|
50
|
+
end
|
51
|
+
|
52
|
+
module Parser
|
53
|
+
PATTERN = %r{\A(?:
|
54
|
+
([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
|
55
|
+
(?:-([a-z]{4}))? # script
|
56
|
+
(?:-([a-z]{2}|\d{3}))? # region
|
57
|
+
(?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant
|
58
|
+
(?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension
|
59
|
+
(?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag
|
60
|
+
(x(?:-[0-9a-z]{1,8})+)| # privateuse tag
|
61
|
+
/* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered
|
62
|
+
)\z}xi
|
63
|
+
|
64
|
+
class << self
|
65
|
+
def match(tag)
|
66
|
+
c = PATTERN.match(tag.to_s).captures
|
67
|
+
c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
|
68
|
+
rescue
|
69
|
+
false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Simple Locale tag implementation that computes subtags by simply splitting
|
4
|
+
# the locale tag at '-' occurences.
|
5
|
+
module I18n
|
6
|
+
module Locale
|
7
|
+
module Tag
|
8
|
+
class Simple
|
9
|
+
class << self
|
10
|
+
def tag(tag)
|
11
|
+
new(tag)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
include Parents
|
16
|
+
|
17
|
+
attr_reader :tag
|
18
|
+
|
19
|
+
def initialize(*tag)
|
20
|
+
@tag = tag.join('-').to_sym
|
21
|
+
end
|
22
|
+
|
23
|
+
def subtags
|
24
|
+
@subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_sym
|
28
|
+
tag
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
tag.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_a
|
36
|
+
subtags
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/test/all.rb
CHANGED
data/test/api/basics.rb
CHANGED
data/test/api/interpolation.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Tests
|
2
4
|
module Backend
|
3
5
|
module Api
|
4
6
|
module Interpolation
|
5
|
-
def interpolate(
|
6
|
-
|
7
|
+
def interpolate(*args)
|
8
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
9
|
+
key = args.pop
|
10
|
+
I18n.backend.translate('en', key, options)
|
7
11
|
end
|
8
|
-
|
12
|
+
|
9
13
|
def test_interpolation_given_no_interpolation_values_it_does_not_alter_the_string
|
10
14
|
assert_equal 'Hi {{name}}!', interpolate(:default => 'Hi {{name}}!')
|
11
15
|
end
|
@@ -18,6 +22,33 @@ module Tests
|
|
18
22
|
assert_equal 'Hi !', interpolate(:default => 'Hi {{name}}!', :name => nil)
|
19
23
|
end
|
20
24
|
|
25
|
+
def test_interpolation_given_a_lambda_as_a_value_it_calls_it_when_the_string_contains_the_key
|
26
|
+
assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => lambda { 'David' })
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_interpolation_given_a_lambda_as_a_value_it_does_not_call_it_when_the_string_does_not_contain_the_key
|
30
|
+
assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { raise 'fail' }) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_interpolation_given_interpolation_values_but_missing_a_key_it_raises_a_missing_interpolation_argument_exception
|
34
|
+
assert_raises(I18n::MissingInterpolationArgument) do
|
35
|
+
interpolate(:default => '{{foo}}', :bar => 'bar')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_interpolation_does_not_raise_missing_interpolation_argument_exceptions_for_escaped_variables
|
40
|
+
assert_nothing_raised(I18n::MissingInterpolationArgument) do
|
41
|
+
assert_equal 'Barr {{foo}}', interpolate(:default => '{{bar}} \{{foo}}', :bar => 'Barr')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_interpolation_does_not_change_the_original_stored_translation_string_and_allows_reinterpolation
|
46
|
+
I18n.backend.store_translations(:en, :interpolate => 'Hi {{name}}!')
|
47
|
+
assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David')
|
48
|
+
assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda')
|
49
|
+
# assert_equal 'Hi {{name}}!', I18n.backend.instance_variable_get(:@translations)[:en][:interpolate]
|
50
|
+
end
|
51
|
+
|
21
52
|
def test_interpolate_with_ruby_1_9_syntax
|
22
53
|
assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
|
23
54
|
end
|
@@ -60,4 +91,4 @@ module Tests
|
|
60
91
|
end
|
61
92
|
end
|
62
93
|
end
|
63
|
-
end
|
94
|
+
end
|