pepe-i18n 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.textile +57 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +42 -0
- data/Rakefile +21 -0
- data/VERSION +1 -0
- data/lib/i18n.rb +270 -0
- data/lib/i18n/backend/base.rb +251 -0
- data/lib/i18n/backend/cache.rb +71 -0
- data/lib/i18n/backend/chain.rb +64 -0
- data/lib/i18n/backend/fallbacks.rb +53 -0
- data/lib/i18n/backend/gettext.rb +65 -0
- data/lib/i18n/backend/pluralization.rb +56 -0
- data/lib/i18n/backend/simple.rb +23 -0
- data/lib/i18n/exceptions.rb +61 -0
- data/lib/i18n/gettext.rb +25 -0
- data/lib/i18n/helpers/gettext.rb +35 -0
- data/lib/i18n/locale/fallbacks.rb +100 -0
- data/lib/i18n/locale/tag.rb +27 -0
- data/lib/i18n/locale/tag/parents.rb +24 -0
- data/lib/i18n/locale/tag/rfc4646.rb +78 -0
- data/lib/i18n/locale/tag/simple.rb +44 -0
- data/lib/i18n/string.rb +95 -0
- data/test/all.rb +5 -0
- data/test/api/basics.rb +15 -0
- data/test/api/interpolation.rb +85 -0
- data/test/api/lambda.rb +52 -0
- data/test/api/link.rb +47 -0
- data/test/api/localization/date.rb +65 -0
- data/test/api/localization/date_time.rb +63 -0
- data/test/api/localization/lambda.rb +26 -0
- data/test/api/localization/time.rb +63 -0
- data/test/api/pluralization.rb +37 -0
- data/test/api/translation.rb +51 -0
- data/test/backend/cache/cache_test.rb +57 -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 +79 -0
- data/test/backend/fallbacks/fallbacks_test.rb +29 -0
- data/test/backend/pluralization/api_test.rb +81 -0
- data/test/backend/pluralization/pluralization_test.rb +39 -0
- data/test/backend/simple/all.rb +5 -0
- data/test/backend/simple/api_test.rb +90 -0
- data/test/backend/simple/lookup_test.rb +24 -0
- data/test/backend/simple/setup.rb +147 -0
- data/test/backend/simple/translations_test.rb +89 -0
- data/test/fixtures/locales/de.po +61 -0
- data/test/fixtures/locales/en.rb +3 -0
- data/test/fixtures/locales/en.yml +3 -0
- data/test/fixtures/locales/plurals.rb +112 -0
- data/test/gettext/api_test.rb +78 -0
- data/test/gettext/backend_test.rb +35 -0
- data/test/i18n_exceptions_test.rb +97 -0
- data/test/i18n_load_path_test.rb +23 -0
- data/test/i18n_test.rb +163 -0
- data/test/locale/fallbacks_test.rb +128 -0
- data/test/locale/tag/rfc4646_test.rb +147 -0
- data/test/locale/tag/simple_test.rb +35 -0
- data/test/string_test.rb +94 -0
- data/test/test_helper.rb +71 -0
- data/test/with_options.rb +34 -0
- metadata +151 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'i18n/locale/tag'
|
4
|
+
|
5
|
+
# Locale Fallbacks
|
6
|
+
#
|
7
|
+
# Extends the I18n module to hold a fallbacks instance which is set to an
|
8
|
+
# instance of I18n::Locale::Fallbacks by default but can be swapped with a
|
9
|
+
# different implementation.
|
10
|
+
#
|
11
|
+
# Locale fallbacks will compute a number of fallback locales for a given locale.
|
12
|
+
# For example:
|
13
|
+
#
|
14
|
+
# <pre><code>
|
15
|
+
# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] </code></pre>
|
16
|
+
#
|
17
|
+
# Locale fallbacks always fall back to
|
18
|
+
#
|
19
|
+
# * all parent locales of a given locale (e.g. :es for :"es-MX") first,
|
20
|
+
# * the current default locales and all of their parents second
|
21
|
+
#
|
22
|
+
# The default locales are set to [I18n.default_locale] by default but can be
|
23
|
+
# set to something else.
|
24
|
+
#
|
25
|
+
# One can additionally add any number of additional fallback locales manually.
|
26
|
+
# These will be added before the default locales to the fallback chain. For
|
27
|
+
# example:
|
28
|
+
#
|
29
|
+
# # using the default locale as default fallback locale
|
30
|
+
#
|
31
|
+
# I18n.default_locale = :"en-US"
|
32
|
+
# I18n.fallbacks = I18n::Fallbacks.new(:"de-AT" => :"de-DE")
|
33
|
+
# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en]
|
34
|
+
#
|
35
|
+
# # using a custom locale as default fallback locale
|
36
|
+
#
|
37
|
+
# I18n.fallbacks = I18n::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de)
|
38
|
+
# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en]
|
39
|
+
# I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en]
|
40
|
+
#
|
41
|
+
# # mapping fallbacks to an existing instance
|
42
|
+
#
|
43
|
+
# # people speaking Catalan also speak Spanish as spoken in Spain
|
44
|
+
# fallbacks = I18n.fallbacks
|
45
|
+
# fallbacks.map(:ca => :"es-ES")
|
46
|
+
# fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
|
47
|
+
#
|
48
|
+
# # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel
|
49
|
+
# fallbacks.map(:"ar-PS" => :"he-IL")
|
50
|
+
# fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
|
51
|
+
# fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
|
52
|
+
#
|
53
|
+
# # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland
|
54
|
+
# fallbacks.map(:sms => [:"se-FI", :"fi-FI"])
|
55
|
+
# fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
|
56
|
+
|
57
|
+
module I18n
|
58
|
+
module Locale
|
59
|
+
class Fallbacks < Hash
|
60
|
+
def initialize(*mappings)
|
61
|
+
@map = {}
|
62
|
+
map(mappings.pop) if mappings.last.is_a?(Hash)
|
63
|
+
self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings
|
64
|
+
end
|
65
|
+
|
66
|
+
def defaults=(defaults)
|
67
|
+
@defaults = defaults.map { |default| compute(default, false) }.flatten
|
68
|
+
end
|
69
|
+
attr_reader :defaults
|
70
|
+
|
71
|
+
def [](locale)
|
72
|
+
raise InvalidLocale.new(locale) if locale.nil?
|
73
|
+
locale = locale.to_sym
|
74
|
+
super || store(locale, compute(locale))
|
75
|
+
end
|
76
|
+
|
77
|
+
def map(mappings)
|
78
|
+
mappings.each do |from, to|
|
79
|
+
from, to = from.to_sym, Array(to)
|
80
|
+
to.each do |to|
|
81
|
+
@map[from] ||= []
|
82
|
+
@map[from] << to.to_sym
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def compute(tags, include_defaults = true)
|
90
|
+
result = Array(tags).collect do |tag|
|
91
|
+
tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym }
|
92
|
+
tags.each { |tag| tags += compute(@map[tag]) if @map[tag] }
|
93
|
+
tags
|
94
|
+
end.flatten
|
95
|
+
result.push(*defaults) if include_defaults
|
96
|
+
result.uniq
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'i18n/locale/tag/simple'
|
4
|
+
require 'i18n/locale/tag/rfc4646'
|
5
|
+
|
6
|
+
module I18n
|
7
|
+
module Locale
|
8
|
+
module Tag
|
9
|
+
class << self
|
10
|
+
# Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+.
|
11
|
+
def implementation
|
12
|
+
@@implementation ||= Simple
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets the current locale tag implementation. Use this to set a different locale tag implementation.
|
16
|
+
def implementation=(implementation)
|
17
|
+
@@implementation = implementation
|
18
|
+
end
|
19
|
+
|
20
|
+
# Factory method for locale tags. Delegates to the current locale tag implementation.
|
21
|
+
def tag(tag)
|
22
|
+
implementation.tag(tag)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
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,78 @@
|
|
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
|
+
require 'i18n/locale/tag/parents'
|
11
|
+
|
12
|
+
module I18n
|
13
|
+
module Locale
|
14
|
+
module Tag
|
15
|
+
RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ]
|
16
|
+
RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase }
|
17
|
+
|
18
|
+
class Rfc4646 < Struct.new(*RFC4646_SUBTAGS)
|
19
|
+
class << self
|
20
|
+
# Parses the given tag and returns a Tag instance if it is valid.
|
21
|
+
# Returns false if the given tag is not valid according to RFC 4646.
|
22
|
+
def tag(tag)
|
23
|
+
matches = parser.match(tag)
|
24
|
+
new(*matches) if matches
|
25
|
+
end
|
26
|
+
|
27
|
+
def parser
|
28
|
+
@@parser ||= Rfc4646::Parser
|
29
|
+
end
|
30
|
+
|
31
|
+
def parser=(parser)
|
32
|
+
@@parser = parser
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
include Parents
|
37
|
+
|
38
|
+
RFC4646_FORMATS.each do |name, format|
|
39
|
+
define_method(name) { self[name].send(format) unless self[name].nil? }
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_sym
|
43
|
+
to_s.to_sym
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
@tag ||= to_a.compact.join("-")
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_a
|
51
|
+
members.collect { |attr| self.send(attr) }
|
52
|
+
end
|
53
|
+
|
54
|
+
module Parser
|
55
|
+
PATTERN = %r{\A(?:
|
56
|
+
([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
|
57
|
+
(?:-([a-z]{4}))? # script
|
58
|
+
(?:-([a-z]{2}|\d{3}))? # region
|
59
|
+
(?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant
|
60
|
+
(?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension
|
61
|
+
(?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag
|
62
|
+
(x(?:-[0-9a-z]{1,8})+)| # privateuse tag
|
63
|
+
/* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered
|
64
|
+
)\z}xi
|
65
|
+
|
66
|
+
class << self
|
67
|
+
def match(tag)
|
68
|
+
c = PATTERN.match(tag.to_s).captures
|
69
|
+
c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
|
70
|
+
rescue
|
71
|
+
false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'i18n/locale/tag/parents'
|
4
|
+
|
5
|
+
# Simple Locale tag implementation that computes subtags by simply splitting
|
6
|
+
# the locale tag at '-' occurences.
|
7
|
+
|
8
|
+
module I18n
|
9
|
+
module Locale
|
10
|
+
module Tag
|
11
|
+
class Simple
|
12
|
+
class << self
|
13
|
+
def tag(tag)
|
14
|
+
new(tag)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
include Parents
|
19
|
+
|
20
|
+
attr_reader :tag
|
21
|
+
|
22
|
+
def initialize(*tag)
|
23
|
+
@tag = tag.join('-').to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def subtags
|
27
|
+
@subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_sym
|
31
|
+
tag
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
tag.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_a
|
39
|
+
subtags
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/i18n/string.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
=begin
|
4
|
+
heavily based on Masao Mutoh's gettext String interpolation extension
|
5
|
+
http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
|
6
|
+
Copyright (C) 2005-2009 Masao Mutoh
|
7
|
+
You may redistribute it and/or modify it under the same license terms as Ruby.
|
8
|
+
=end
|
9
|
+
|
10
|
+
if RUBY_VERSION < '1.9'
|
11
|
+
|
12
|
+
# KeyError is raised by String#% when the string contains a named placeholder
|
13
|
+
# that is not contained in the given arguments hash. Ruby 1.9 includes and
|
14
|
+
# raises this exception natively. We define it to mimic Ruby 1.9's behaviour
|
15
|
+
# in Ruby 1.8.x
|
16
|
+
|
17
|
+
class KeyError < IndexError
|
18
|
+
def initialize(message = nil)
|
19
|
+
super(message || "key not found")
|
20
|
+
end
|
21
|
+
end unless defined?(KeyError)
|
22
|
+
|
23
|
+
# Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
|
24
|
+
#
|
25
|
+
# String#% method which accept "named argument". The translator can know
|
26
|
+
# the meaning of the msgids using "named argument" instead of %s/%d style.
|
27
|
+
|
28
|
+
class String
|
29
|
+
# For older ruby versions, such as ruby-1.8.5
|
30
|
+
alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
|
31
|
+
alias :interpolate_without_ruby_19_syntax :% # :nodoc:
|
32
|
+
|
33
|
+
INTERPOLATION_PATTERN = Regexp.union(
|
34
|
+
/%%/,
|
35
|
+
/%\{(\w+)\}/, # matches placeholders like "%{foo}"
|
36
|
+
/%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
|
37
|
+
)
|
38
|
+
|
39
|
+
# % uses self (i.e. the String) as a format specification and returns the
|
40
|
+
# result of applying it to the given arguments. In other words it interpolates
|
41
|
+
# the given arguments to the string according to the formats the string
|
42
|
+
# defines.
|
43
|
+
#
|
44
|
+
# There are three ways to use it:
|
45
|
+
#
|
46
|
+
# * Using a single argument or Array of arguments.
|
47
|
+
#
|
48
|
+
# This is the default behaviour of the String class. See Kernel#sprintf for
|
49
|
+
# more details about the format string.
|
50
|
+
#
|
51
|
+
# Example:
|
52
|
+
#
|
53
|
+
# "%d %s" % [1, "message"]
|
54
|
+
# # => "1 message"
|
55
|
+
#
|
56
|
+
# * Using a Hash as an argument and unformatted, named placeholders.
|
57
|
+
#
|
58
|
+
# When you pass a Hash as an argument and specify placeholders with %{foo}
|
59
|
+
# it will interpret the hash values as named arguments.
|
60
|
+
#
|
61
|
+
# Example:
|
62
|
+
#
|
63
|
+
# "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
|
64
|
+
# # => "Masao Mutoh"
|
65
|
+
#
|
66
|
+
# * Using a Hash as an argument and formatted, named placeholders.
|
67
|
+
#
|
68
|
+
# When you pass a Hash as an argument and specify placeholders with %<foo>d
|
69
|
+
# it will interpret the hash values as named arguments and format the value
|
70
|
+
# according to the formatting instruction appended to the closing >.
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
#
|
74
|
+
# "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
|
75
|
+
# # => "10, 43.3"
|
76
|
+
def %(args)
|
77
|
+
if args.kind_of?(Hash)
|
78
|
+
dup.gsub(INTERPOLATION_PATTERN) do |match|
|
79
|
+
if match == '%%'
|
80
|
+
'%'
|
81
|
+
else
|
82
|
+
key = ($1 || $2).to_sym
|
83
|
+
raise KeyError unless args.has_key?(key)
|
84
|
+
$3 ? sprintf("%#{$3}", args[key]) : args[key]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
elsif self =~ INTERPOLATION_PATTERN
|
88
|
+
raise ArgumentError.new('one hash required')
|
89
|
+
else
|
90
|
+
result = gsub(/%([{<])/, '%%\1')
|
91
|
+
result.send :'interpolate_without_ruby_19_syntax', args
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/test/all.rb
ADDED
data/test/api/basics.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tests
|
4
|
+
module Backend
|
5
|
+
module Api
|
6
|
+
module Basics
|
7
|
+
def test_available_locales
|
8
|
+
backend_store_translations 'de', :foo => 'bar'
|
9
|
+
backend_store_translations 'en', :foo => 'foo'
|
10
|
+
assert_equal ['de', 'en'], I18n.backend.available_locales.map{|locale| locale.to_s }.sort
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Tests
|
4
|
+
module Backend
|
5
|
+
module Api
|
6
|
+
module Interpolation
|
7
|
+
def interpolate(options)
|
8
|
+
I18n.backend.translate('en', nil, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_interpolation_given_no_interpolation_values_it_does_not_alter_the_string
|
12
|
+
assert_equal 'Hi {{name}}!', interpolate(:default => 'Hi {{name}}!')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_interpolation_given_interpolation_values_it_interpolates_the_values_to_the_string
|
16
|
+
assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => 'David')
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_interpolation_given_interpolation_values_with_nil_values_it_interpolates_the_values_to_the_string
|
20
|
+
assert_equal 'Hi !', interpolate(:default => 'Hi {{name}}!', :name => nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_interpolation_given_a_lambda_as_a_value_it_calls_it_when_the_string_contains_the_key
|
24
|
+
assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => lambda { 'David' })
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_interpolation_given_a_lambda_as_a_value_it_does_not_call_it_when_the_string_does_not_contain_the_key
|
28
|
+
assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { raise 'fail' }) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_interpolation_given_interpolation_values_but_missing_a_key_it_raises_a_missing_interpolation_argument_exception
|
32
|
+
assert_raises(I18n::MissingInterpolationArgument) do
|
33
|
+
interpolate(:default => '{{foo}}', :bar => 'bar')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_interpolation_does_not_raise_missing_interpolation_argument_exceptions_for_escaped_variables
|
38
|
+
assert_nothing_raised(I18n::MissingInterpolationArgument) do
|
39
|
+
assert_equal 'Barr {{foo}}', interpolate(:default => '{{bar}} \{{foo}}', :bar => 'Barr')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_interpolate_with_ruby_1_9_syntax
|
44
|
+
assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_interpolate_given_a_value_hash_interpolates_into_unicode_string
|
48
|
+
assert_equal 'Häi David!', interpolate(:default => 'Häi {{name}}!', :name => 'David')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_interpolate_given_a_unicode_value_hash_interpolates_to_the_string
|
52
|
+
assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi {{name}}!', :name => 'ゆきひろ')
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_interpolate_given_a_unicode_value_hash_interpolates_into_unicode_string
|
56
|
+
assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、{{name}}さん!', :name => 'ゆきひろ')
|
57
|
+
end
|
58
|
+
|
59
|
+
if Kernel.const_defined?(:Encoding)
|
60
|
+
def test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding
|
61
|
+
assert_equal euc_jp('Hi ゆきひろ!'), interpolate(:default => 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_interpolate_given_a_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error
|
65
|
+
assert_raises(Encoding::CompatibilityError) do
|
66
|
+
interpolate(:default => euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error
|
71
|
+
assert_raises(Encoding::CompatibilityError) do
|
72
|
+
interpolate(:default => 'こんにちは、{{name}}さん!', :name => euc_jp('ゆきひろ'))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key
|
78
|
+
assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{default}}', :foo => :bar) }
|
79
|
+
assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{scope}}', :foo => :bar) }
|
80
|
+
assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{separator}}', :foo => :bar) }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|