i18n-inflector 2.1.0 → 2.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.
@@ -22,14 +22,70 @@ module I18n
22
22
  # the translation method. Such option should have the name of a
23
23
  # global option but prefixed with +inflector_+:
24
24
  # translate('welcome', :inflector_<option_name> => value)
25
+ # @note This class uses modified version of +attr_accessor+ that
26
+ # memorizes any added method name as an option name. These options
27
+ # (with +inflector_+ prefix added) are accessible through
28
+ # {#known} method. The last method is used by options preparing
29
+ # routine when the interpolation is performed.
25
30
  class InflectionOptions
26
31
 
32
+ # Prefix used to mark option as a controlling option.
33
+ OPTION_PREFIX = 'inflector_'
34
+
35
+ class <<self
36
+
37
+ # @private
38
+ def known
39
+ @known
40
+ end
41
+
42
+ # @private
43
+ alias old_attr_accessor attr_accessor
44
+ def attr_accessor(*args)
45
+ r = old_attr_accessor(*args)
46
+ @known ||= Hash.new
47
+ args.each do |arg|
48
+ key = '@' + arg.to_s
49
+ @known[key.to_sym] = (OPTION_PREFIX + arg.to_s).to_sym
50
+ end
51
+ r
52
+ end
53
+
54
+ end
55
+
56
+ # This switch enables cache-aware mode. In that mode inflection
57
+ # options and flags are evaluated before calling original translate
58
+ # method and all options are passed to that method. Because options
59
+ # preparation for inflection methods is explicit (any missing switches
60
+ # and their default values are added to options) then original
61
+ # translate (or proxy caching method) will receive even those options
62
+ # that might have been changed globally.
63
+ #
64
+ # Caching modules for I18n may use options passed to the translate
65
+ # method (if they are plugged in before inflector) for key
66
+ # transformation since the inflection options may influence
67
+ # the interpolation process and therefore the resulting string.
68
+ #
69
+ # If however, the caching variant of the translate method is
70
+ # positioned before inflected variant in methods chain, then
71
+ # the only way of knowing all the settings by caching routine is to call
72
+ # <tt>options.options.prepare_options!(options)</tt> on the used backend,
73
+ # for example:
74
+ # I18n.backend.inflector.options.prepare(options)
75
+ # That will alter the +options+ data so they will contain all switches
76
+ # and values.
77
+ #
78
+ # @api public
79
+ # @return [Boolean] state of the switch
80
+ # @param [Boolean] state +true+ enables, +false+ disables this switch
81
+ attr_accessor :cache_aware
82
+
27
83
  # This is a switch that enables extended error reporting. When it's enabled then
28
84
  # errors are raised in case of unknown or empty tokens present in a pattern
29
85
  # or in options. This switch is by default set to +false+.
30
86
  #
31
- # @note Local option +:raises+ passed to the {I18n::Backend::Inflector#translate}
32
- # overrides this setting.
87
+ # @note Local option +:inflector_raises+ passed
88
+ # to the {I18n::Backend::Inflector#translate} overrides this setting.
33
89
  #
34
90
  # @api public
35
91
  # @return [Boolean] state of the switch
@@ -41,8 +97,8 @@ module I18n
41
97
  # may make your translation data a bit messy if you're not alert.
42
98
  # That's why this switch is by default set to +false+.
43
99
  #
44
- # @note Local option +:aliased_patterns+ passed to the {I18n::Backend::Inflector#translate}
45
- # overrides this setting.
100
+ # @note Local option +:inflector_aliased_patterns+ passed to the
101
+ # {I18n::Backend::Inflector#translate} overrides this setting.
46
102
  #
47
103
  # @api public
48
104
  # @return [Boolean] state of the switch
@@ -50,13 +106,14 @@ module I18n
50
106
  attr_accessor :aliased_patterns
51
107
 
52
108
  # When this switch is set to +true+ then inflector falls back to the default
53
- # token for a kind if an inflection option passed to the {I18n::Backend::Inflector#translate} is unknown
54
- # or +nil+. Note that the value of the default token will be
109
+ # token for a kind if an inflection option passed to the
110
+ # {I18n::Backend::Inflector#translate} is unknown or +nil+.
111
+ # Note that the value of the default token will be
55
112
  # interpolated only when this token is present in a pattern. This switch
56
113
  # is by default set to +true+.
57
114
  #
58
- # @note Local option +:unknown_defaults+ passed to the {I18n::Backend::Inflector#translate}
59
- # overrides this setting.
115
+ # @note Local option +:inflector_unknown_defaults+ passed
116
+ # to the {I18n::Backend::Inflector#translate} overrides this setting.
60
117
  #
61
118
  # @api public
62
119
  # @return [Boolean] state of the switch
@@ -85,7 +142,7 @@ module I18n
85
142
  # # :gender option is not present,
86
143
  # # unknown tokens from options are not falling back to default
87
144
  #
88
- # I18n.t('welcome', :unknown_defaults => false)
145
+ # I18n.t('welcome', :inflector_unknown_defaults => false)
89
146
  # # => "Dear You"
90
147
  #
91
148
  # # other way of setting an option – globally
@@ -97,7 +154,7 @@ module I18n
97
154
  # # :gender option is not present, free text is present,
98
155
  # # unknown tokens from options are not falling back to default
99
156
  #
100
- # I18n.t('welcome_free', :unknown_defaults => false)
157
+ # I18n.t('welcome_free', :inflector_unknown_defaults => false)
101
158
  # # => "Dear You"
102
159
  #
103
160
  # @example Example 2
@@ -111,13 +168,13 @@ module I18n
111
168
  # # :gender option is nil
112
169
  # # unknown tokens from options are not falling back to default token for a kind
113
170
  #
114
- # I18n.t('welcome', :gender => nil, :unknown_defaults => false)
171
+ # I18n.t('welcome', :gender => nil, :inflector_unknown_defaults => false)
115
172
  # # => "Dear "
116
173
  #
117
174
  # # :gender option is nil, free text is present
118
175
  # # unknown tokens from options are not falling back to default token for a kind
119
176
  #
120
- # I18n.t('welcome_free', :gender => nil, :unknown_defaults => false)
177
+ # I18n.t('welcome_free', :gender => nil, :inflector_unknown_defaults => false)
121
178
  # # => "Dear Free"
122
179
  #
123
180
  # @example Example 3
@@ -131,20 +188,21 @@ module I18n
131
188
  # # :gender option is unknown,
132
189
  # # unknown tokens from options are not falling back to default token for a kind
133
190
  #
134
- # I18n.t('welcome', :gender => :unknown_blabla, :unknown_defaults => false)
191
+ # I18n.t('welcome', :gender => :unknown_blabla, :inflector_unknown_defaults => false)
135
192
  # # => "Dear "
136
193
  #
137
194
  # # :gender option is unknown, free text is present
138
195
  # # unknown tokens from options are not falling back to default token for a kind
139
196
  #
140
- # I18n.t('welcome_free', :gender => :unknown_blabla, :unknown_defaults => false)
197
+ # I18n.t('welcome_free', :gender => :unknown_blabla, :inflector_unknown_defaults => false)
141
198
  # # => "Dear Free"
142
199
  attr_accessor :unknown_defaults
143
200
 
144
201
  # When this switch is set to +true+ then inflector falls back to the default
145
- # token for a kind if the given inflection option is correct but doesn't exist in a pattern.
202
+ # token for a kind if the given inflection option is correct but doesn't exist
203
+ # in a pattern.
146
204
  #
147
- # There might happend that the inflection option
205
+ # There might happen that the inflection option
148
206
  # given to {#translate} method will contain some proper token, but that token
149
207
  # will not be present in a processed pattern. Normally an empty string will
150
208
  # be generated from such a pattern or a free text (if a local fallback is present
@@ -153,7 +211,7 @@ module I18n
153
211
  #
154
212
  # This switch is by default set to +false+.
155
213
  #
156
- # @note Local option +:excluded_defaults+ passed to the {I18n::Backend::Inflector#translate}
214
+ # @note Local option +:inflector_excluded_defaults+ passed to the {I18n::Backend::Inflector#translate}
157
215
  # overrides this setting.
158
216
  #
159
217
  # @api public
@@ -171,11 +229,11 @@ module I18n
171
229
  # default: n
172
230
  #
173
231
  # welcome: 'Dear @{n:You|m:Sir}'
174
- # @example Usage of +:excluded_defaults+ option
232
+ # @example Usage of +:inflector_excluded_defaults+ option
175
233
  # I18n.t('welcome', :gender => :o)
176
234
  # # => "Dear "
177
235
  #
178
- # I18n.t('welcome', :gender => :o, :excluded_defaults => true)
236
+ # I18n.t('welcome', :gender => :o, :inflector_excluded_defaults => true)
179
237
  # # => "Dear You"
180
238
  attr_accessor :excluded_defaults
181
239
 
@@ -188,13 +246,51 @@ module I18n
188
246
  #
189
247
  # @return [void]
190
248
  def reset
191
- @excluded_defaults = false
192
249
  @unknown_defaults = true
250
+ @excluded_defaults = false
193
251
  @aliased_patterns = false
252
+ @cache_aware = false
194
253
  @raises = false
195
254
  nil
196
255
  end
197
256
 
257
+ # This method processes the given argument
258
+ # in a way that it will use default values
259
+ # for options that are missing.
260
+ #
261
+ # @api public
262
+ # @note It modifies the given object.
263
+ # @param [Hash] options the options
264
+ # @return [Hash] the given options
265
+ def prepare_options!(options)
266
+ self.class.known.
267
+ reject { |name,long| options.has_key?(long) }.
268
+ each { |name,long| options[long] = instance_variable_get(name) }
269
+ options
270
+ end
271
+
272
+ # This method prepares options for translate method.
273
+ # That means removal of all kind-related options
274
+ # and all options that are flags.
275
+ #
276
+ # @api public
277
+ # @note It modifies the given object.
278
+ # @param [Hash] options the given options
279
+ # @return [Hash] the given options
280
+ def clean_for_translate!(options)
281
+ self.class.known.each { |name,long| options.delete long }
282
+ options
283
+ end
284
+
285
+ # Lists all known options in a long format
286
+ # (each name preceeded by <tt>inflector_</tt>).
287
+ #
288
+ # @api public
289
+ # @return [Array<Symbol>] the known options
290
+ def known
291
+ self.class.known.values
292
+ end
293
+
198
294
  end
199
295
 
200
296
  end
@@ -14,7 +14,7 @@ module I18n
14
14
  # @private
15
15
  EMAIL = 'pw@gnu.org'
16
16
  # @private
17
- VERSION = '2.1.0'
17
+ VERSION = '2.2.0'
18
18
  # @private
19
19
  NAME = 'i18n-inflector'
20
20
  # @private
@@ -3,13 +3,16 @@
3
3
  require 'i18n'
4
4
 
5
5
  require 'i18n-inflector/version'
6
+ require 'i18n-inflector/hset'
6
7
  require 'i18n-inflector/lazy_enum'
7
8
  require 'i18n-inflector/inflection_data_strict'
8
9
  require 'i18n-inflector/inflection_data'
9
10
  require 'i18n-inflector/options'
10
- require 'i18n-inflector/backend'
11
11
  require 'i18n-inflector/inflector'
12
+ require 'i18n-inflector/config'
13
+ require 'i18n-inflector/backend'
12
14
  require 'i18n-inflector/errors'
15
+ require 'i18n-inflector/interpolate'
13
16
  require 'i18n-inflector/api_strict'
14
17
  require 'i18n-inflector/api'
15
18
 
@@ -73,18 +73,27 @@ class I18nInflectorTest < Test::Unit::TestCase
73
73
  end
74
74
 
75
75
  test "backend inflector store_translations: raises I18n::BadInflectionAlias when bad alias is given" do
76
- assert_raise I18n::BadInflectionAlias do
77
- store_translations(:xx, :i18n => { :inflections => { :gender => { :o => '@nonexistant' }}})
78
- end
79
- assert_raise I18n::BadInflectionAlias do
80
- store_translations(:xx, :i18n => { :inflections => { :gender => { :default => '@nonexistant' }}})
81
- end
82
- assert_raise I18n::BadInflectionAlias do
83
- store_translations(:xx, :i18n => { :inflections => { :@gender => { :oh => '@nonex' }}})
84
- end
85
- assert_raise I18n::BadInflectionAlias do
86
- store_translations(:xx, :i18n => { :inflections => { :@gender => { :default => '@nonex' }}})
87
- end
76
+ assert_raise I18n::BadInflectionAlias do
77
+ store_translations(:xx, :i18n => { :inflections => { :gender => { :o => '@xnonexistant' }}})
78
+ end
79
+ end
80
+
81
+ test "backend inflector store_translations: raises I18n::BadInflectionAlias when bad default is given" do
82
+ assert_raise I18n::BadInflectionAlias do
83
+ store_translations(:xx, :i18n => { :inflections => { :gender => { :default => '@ynonexistant' }}})
84
+ end
85
+ end
86
+
87
+ test "backend inflector strict store_translations: raises I18n::BadInflectionAlias when bad alias is given" do
88
+ assert_raise I18n::BadInflectionAlias do
89
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { :oh => '@znonex' }}})
90
+ end
91
+ end
92
+
93
+ test "backend inflector strict store_translations: raises I18n::BadInflectionAlias when bad default is given" do
94
+ assert_raise I18n::BadInflectionAlias do
95
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { :default => '@cnonex' }}})
96
+ end
88
97
  end
89
98
 
90
99
  test "backend inflector store_translations: raises I18n::BadInflectionToken when bad token is given" do
@@ -108,6 +117,9 @@ class I18nInflectorTest < Test::Unit::TestCase
108
117
  assert_equal '@{f:AAAAA|m:BBBBB}', I18n.t('escaped_welcome', :gender => 'f', :locale => :xx)
109
118
  store_translations(:xx, 'escaped_welcome' => '\@{f:AAAAA|m:BBBBB}')
110
119
  assert_equal '@{f:AAAAA|m:BBBBB}', I18n.t('escaped_welcome', :gender => 'f', :locale => :xx)
120
+ assert_equal 'Dear All!', I18n.t('welcome', :gender => nil, :locale => :xx, :inflector_unknown_defaults => false)
121
+ store_translations(:xx, 'escaped_welcome' => 'Dear \@{f:Lady|m:Sir|n:You|All}!');
122
+ assert_equal 'Dear @{f:Lady|m:Sir|n:You|All}!', I18n.t('escaped_welcome', :locale => :xx, :inflector_unknown_defaults => false)
111
123
  end
112
124
 
113
125
  test "backend inflector translate: picks Lady for :f gender option" do
@@ -162,7 +174,12 @@ class I18nInflectorTest < Test::Unit::TestCase
162
174
  assert_equal 'Dear All!', I18n.t('welcome', :gender => nil, :locale => :xx, :inflector_unknown_defaults => false)
163
175
  end
164
176
 
165
- test "backend inflector translate: falls back to default for no gender option when :inflector_unknown_defaults is false" do
177
+ test "backend inflector translate: uses default token when inflection option is set to :default" do
178
+ assert_equal 'Dear You!', I18n.t('welcome', :gender => :default, :locale => :xx, :inflector_unknown_defaults => true)
179
+ assert_equal 'Dear You!', I18n.t('welcome', :gender => :default, :locale => :xx, :inflector_unknown_defaults => false)
180
+ end
181
+
182
+ test "backend inflector translate: falls back to default for no inflection option when :inflector_unknown_defaults is false" do
166
183
  assert_equal 'Dear You!', I18n.t('welcome', :locale => :xx, :inflector_unknown_defaults => false)
167
184
  end
168
185
 
@@ -196,18 +213,18 @@ class I18nInflectorTest < Test::Unit::TestCase
196
213
  tr[:xx][:i18n][:inflections][:gender].delete(:default)
197
214
  store_translations(:xx, :i18n => { :inflections => { :gender => { :o => 'other' }}})
198
215
  assert_raise(I18n::InflectionOptionNotFound) { I18n.t('welcome', :locale => :xx, :inflector_raises => true) }
199
- assert_raise(I18n::InflectionOptionIncorrect) { I18n.t('welcome', :locale => :xx, :gender => "", :inflector_raises => true) }
200
- assert_raise(I18n::InflectionOptionIncorrect) { I18n.t('welcome', :locale => :xx, :gender => nil, :inflector_raises => true) }
216
+ assert_raise(I18n::InvalidInflectionOption) { I18n.t('welcome', :locale => :xx, :gender => "", :inflector_raises => true) }
217
+ assert_raise(I18n::InvalidInflectionOption) { I18n.t('welcome', :locale => :xx, :gender => nil, :inflector_raises => true) }
201
218
  assert_raise I18n::InflectionOptionNotFound do
202
219
  I18n.inflector.options.raises = true
203
220
  I18n.t('welcome', :locale => :xx)
204
221
  end
205
222
  end
206
223
 
207
- test "backend inflector translate: raises I18n::InvalidInflectionToken when bad token is given and inflector_raises is true" do
208
- store_translations(:xx, 'hi' => 'Dear @{f:Lady|o:BAD_TOKEN|n:You|First}!')
209
- assert_raise(I18n::InvalidInflectionToken) { I18n.t('hi', :locale => :xx, :inflector_raises => true) }
210
- assert_raise I18n::InvalidInflectionToken do
224
+ test "backend inflector translate: raises I18n::MisplacedInflectionToken when misplaced token is given and inflector_raises is true" do
225
+ store_translations(:xx, 'hi' => 'Dear @{f:Lady|i:BAD_TOKEN|n:You|First}!')
226
+ assert_raise(I18n::MisplacedInflectionToken) { I18n.t('hi', :locale => :xx, :inflector_raises => true) }
227
+ assert_raise I18n::MisplacedInflectionToken do
211
228
  I18n.inflector.options.raises = true
212
229
  I18n.t('hi', :locale => :xx)
213
230
  end
@@ -236,6 +253,84 @@ class I18nInflectorTest < Test::Unit::TestCase
236
253
  assert_equal 'Dear Dude! Dear Dude!', I18n.t('hi', :gender => :m, :locale => :xx, :test => "Dude")
237
254
  end
238
255
 
256
+ test "backend inflector translate: works with complex patterns" do
257
+ store_translations(:xx, :i18n => { :inflections => { :@tense => { :s => 's', :now => 'now', :past => 'later', :default => 'now' }}})
258
+ store_translations(:xx, 'hi' => '@gender+tense{m+now:he is|f+past:she was} here!')
259
+ assert_equal 'he is here!', I18n.t('hi', :gender => :m, :locale => :xx, :inflector_raises => true)
260
+ assert_equal 'he is here!', I18n.t('hi', :gender => :m, :locale => :xx, :inflector_raises => true)
261
+ assert_equal 'he is here!', I18n.t('hi', :gender => :m, :tense => :s, :locale => :xx, :inflector_excluded_defaults => true)
262
+ assert_equal 'she was here!', I18n.t('hi', :gender => :f, :tense => :past, :locale => :xx, :inflector_raises => true)
263
+ assert_equal 'she was here!', I18n.t('hi', :gender => :feminine, :tense => :past, :locale => :xx, :inflector_raises => true)
264
+ store_translations(:xx, 'hi' => '@gender+tense{masculine+now:he is|feminine+past:she was}')
265
+ assert_equal 'he is', I18n.t('hi', :gender => :m, :tense => :now, :inflector_aliased_patterns => true, :locale => :xx)
266
+ assert_equal 'she was', I18n.t('hi', :gender => :f, :tense => :past, :inflector_aliased_patterns => true, :locale => :xx)
267
+ store_translations(:xx, 'hi' => '@gender+tense{masculine+now:he is|feminine+past:she was}')
268
+ assert_equal 'she was', I18n.t('hi', :gender => :f, :tense => :past, :inflector_aliased_patterns => true, :locale => :xx)
269
+ store_translations(:xx, 'hi' => '@gender+tense{masculine+now:he is|feminine+past:she was}')
270
+ assert_equal 'she was', I18n.t('hi', :gender => :feminine, :tense => :past, :inflector_aliased_patterns => true, :locale => :xx)
271
+ store_translations(:xx, 'hi' => '@gender+tense{masculine+now:he is|m+past:he was}')
272
+ assert_equal 'he was', I18n.t('hi', :gender => :m, :tense => :past, :inflector_aliased_patterns => true, :locale => :xx)
273
+ store_translations(:xx, 'hi' => '@gender+tense{m+now:he is|masculine+past:he was}')
274
+ assert_equal 'he was', I18n.t('hi', :gender => :m, :tense => :past, :inflector_aliased_patterns => true, :locale => :xx)
275
+ store_translations(:xx, 'hi' => '@gender+tense{m+now:~|f+past:she was}')
276
+ assert_equal 'male now', I18n.t('hi', :gender => :m, :tense => :now, :locale => :xx)
277
+ end
278
+
279
+ test "backend inflector translate: works with multiple patterns" do
280
+ store_translations(:xx, 'hi' => '@gender{m:Sir|f:Lady}{m: Lancelot|f: Morgana}')
281
+ assert_equal 'Sir Lancelot', I18n.t('hi', :gender => :m, :locale => :xx)
282
+ assert_equal 'Lady Morgana', I18n.t('hi', :gender => :f, :locale => :xx)
283
+ store_translations(:xx, 'hi' => '@{m:Sir|f:Lady}{m: Lancelot|f: Morgana}')
284
+ assert_equal 'Sir Lancelot', I18n.t('hi', :gender => :m, :locale => :xx)
285
+ assert_equal 'Lady Morgana', I18n.t('hi', :gender => :f, :locale => :xx)
286
+ store_translations(:xx, 'hi' => 'Hi @{m:Sir|f:Lady}{m: Lancelot|f: Morgana}!')
287
+ assert_equal 'Hi Sir Lancelot!', I18n.t('hi', :gender => :m, :locale => :xx)
288
+ end
289
+
290
+ test "backend inflector translate: works with key-based inflections" do
291
+ I18n.backend.store_translations(:xx, '@hi' => { :m => 'Sir', :f => 'Lady', :n => 'You',
292
+ :@free => 'TEST', :@prefix => 'Dear ', :@suffix => '!' })
293
+ assert_equal 'Dear Sir!', I18n.t('@hi', :gender => :m, :locale => :xx, :inflector_raises=>true)
294
+ assert_equal 'Dear Lady!', I18n.t('@hi', :gender => :f, :locale => :xx, :inflector_raises=>true)
295
+ assert_equal 'Dear TEST!', I18n.t('@hi', :gender => :x, :locale => :xx, :inflector_unknown_defaults => false)
296
+ assert_equal 'Dear TEST!', I18n.t('@hi', :gender => :x, :locale => :xx, :inflector_unknown_defaults => false)
297
+ end
298
+
299
+ test "backend inflector translate: raises I18n::ComplexPatternMalformed for malformed complex patterns" do
300
+ store_translations(:xx, :i18n => { :inflections => { :@tense => { :now => 'now', :past => 'later', :default => 'now' }}})
301
+ store_translations(:xx, 'hi' => '@gender+tense{m+now+cos:he is|f+past:she was} here!')
302
+ assert_raise I18n::ComplexPatternMalformed do
303
+ I18n.t('hi', :gender => :m, :person => :you, :locale => :xx, :inflector_raises => true)
304
+ end
305
+ store_translations(:xx, 'hi' => '@gender+tense{m+:he is|f+past:she was} here!')
306
+ assert_raise I18n::ComplexPatternMalformed do
307
+ I18n.t('hi', :gender => :m, :person => :you, :locale => :xx, :inflector_raises => true)
308
+ end
309
+ store_translations(:xx, 'hi' => '@gender+tense{+:he is|f+past:she was} here!')
310
+ assert_raise I18n::ComplexPatternMalformed do
311
+ I18n.t('hi', :gender => :m, :person => :you, :locale => :xx, :inflector_raises => true)
312
+ end
313
+ store_translations(:xx, 'hi' => '@gender+tense{m:he is|f+past:she was} here!')
314
+ assert_raise I18n::ComplexPatternMalformed do
315
+ I18n.t('hi', :gender => :m, :person => :you, :locale => :xx, :inflector_raises => true)
316
+ end
317
+ end
318
+
319
+ test "backend inflector translate: works with loud tokens" do
320
+ store_translations(:xx, 'hi' => 'Dear @{m:~|n:You|All}!')
321
+ assert_equal 'Dear male!', I18n.t('hi', :gender => :m, :locale => :xx)
322
+ store_translations(:xx, 'hi' => 'Dear @{masculine:~|n:You|All}!')
323
+ assert_equal 'Dear male!', I18n.t('hi', :gender => :m, :locale => :xx, :inflector_aliased_patterns => true)
324
+ store_translations(:xx, 'hi' => 'Dear @{f,m:~|n:You|All}!')
325
+ assert_equal 'Dear male!', I18n.t('hi', :gender => :m, :locale => :xx)
326
+ store_translations(:xx, 'hi' => 'Dear @{!n:~|n:You|All}!')
327
+ assert_equal 'Dear male!', I18n.t('hi', :gender => :m, :locale => :xx)
328
+ store_translations(:xx, 'hi' => 'Dear @{!n:\~|n:You|All}!')
329
+ assert_equal 'Dear ~!', I18n.t('hi', :gender => :m, :locale => :xx)
330
+ store_translations(:xx, 'hi' => 'Dear @{!n:\\\\~|n:You|All}!')
331
+ assert_equal 'Dear \\~!', I18n.t('hi', :gender => :m, :locale => :xx)
332
+ end
333
+
239
334
  test "backend inflector translate: works with tokens separated by commas" do
240
335
  store_translations(:xx, 'hi' => 'Dear @{f,m:Someone|n:You|All}!')
241
336
  assert_equal 'Dear Someone!', I18n.t('hi', :gender => :m, :locale => :xx)
@@ -253,7 +348,7 @@ class I18nInflectorTest < Test::Unit::TestCase
253
348
  assert_equal 'Hello ', I18n.t('hi', :gender => :m, :locale => :xx)
254
349
  assert_equal 'Hello Ladies', I18n.t('hi', :locale => :xx)
255
350
  store_translations(:xx, 'hi' => 'Hello @{!n:Ladies|m,f:You}')
256
- assert_equal 'Hello ', I18n.t('hi', :locale => :xx, :inflector_raises => true)
351
+ assert_equal 'Hello ', I18n.t('hi', :locale => :xx, :inflector_raises => false)
257
352
  end
258
353
 
259
354
  test "backend inflector translate: works with tokens separated by commas and negative tokens" do
@@ -274,6 +369,7 @@ class I18nInflectorTest < Test::Unit::TestCase
274
369
  assert_equal 'Dear Sir!', I18n.t('hi', :gender => :m, :locale => :xx, :inflector_aliased_patterns => true)
275
370
  assert_equal 'Dear Sir!', I18n.t('hi', :gender => :masculine, :locale => :xx, :inflector_aliased_patterns => true)
276
371
  assert_equal 'Dear Lady!', I18n.t('hi', :gender => :f, :locale => :xx, :inflector_aliased_patterns => true)
372
+ assert_equal 'Dear Lady!', I18n.t('hi', :gender => :feminine, :locale => :xx, :inflector_aliased_patterns => true)
277
373
  assert_equal 'Dear All!', I18n.t('hi', :gender => :s, :locale => :xx, :inflector_aliased_patterns => true)
278
374
  assert_equal 'Dear You!', I18n.t('hi', :locale => :xx, :inflector_aliased_patterns => true)
279
375
  I18n.inflector.options.aliased_patterns = true
@@ -298,7 +394,68 @@ class I18nInflectorTest < Test::Unit::TestCase
298
394
  assert_equal 'Dear You!', I18n.t('hi', :gender => :s, :@gender => :unknown, :locale => :xx)
299
395
  assert_equal 'Dear You!', I18n.t('hi', :gender => :s, :@gender => nil, :locale => :xx)
300
396
  assert_equal 'Dear Sir!', I18n.t('hi', :gender => :s, :@gender => :s, :locale => :xx)
397
+ end
398
+
399
+ test "backend inflector translate: is immune to reserved or bad content" do
400
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { :s => 'sir', :o => 'other', :s => 'a', :n => 'n', :default => 'n' }}})
401
+ store_translations(:xx, :i18n => { :inflections => { :@tense => { :now => ''}}})
402
+ store_translations(:xx, 'hi' => 'Dear @nonexistant{s:Sir|o:Other|n:You|All}!')
403
+ assert_equal 'Dear All!', I18n.t('hi', :gender => 'm', :locale => :xx)
404
+ store_translations(:xx, 'hi' => 'Dear @gender{s:Sir|o:Other|n:You|All}!')
405
+ assert_equal 'Dear You!', I18n.t('hi', :gender => '@', :@gender => '+', :locale => :xx)
406
+ assert_equal 'Dear You!', I18n.t('hi', :gender => '', :@gender => '', :locale => :xx)
407
+ store_translations(:xx, 'hi' => '@gender+tense{m+now:~|f+past:she was}')
408
+ assert_equal 'male ', I18n.t('hi', :gender => :m, :tense => :now, :locale => :xx)
409
+ assert_raise I18n::ArgumentError do
410
+ I18n.t('', :gender => :s, :locale => :xx)
411
+ end
412
+ assert_raise I18n::InvalidInflectionKind do
413
+ store_translations(:xx, 'hop' => '@gen,der{m+now:~|f+past:she was}')
414
+ I18n.t('hop', :gender => :s, :locale => :xx, :inflector_raises => true)
415
+ end
416
+ assert_raise I18n::InvalidInflectionToken do
417
+ I18n.backend.store_translations(:xx, 'hop' => '@{m+now:~|f+past:she was}')
418
+ I18n.t('hop', :gender => :s, :locale => :xx, :inflector_raises => true)
419
+ end
420
+ assert_raise I18n::InvalidInflectionKind do
421
+ store_translations(:xx, 'hi' => 'Dear @uuuuuuuu{s:Sir|o:Other|n:You|All}!')
422
+ I18n.t('hi', :gender => 'm', :locale => :xx, :inflector_raises => true)
423
+ end
424
+ assert_raise I18n::MisplacedInflectionToken do
425
+ store_translations(:xx, 'hi' => 'Dear @tense{s:Sir|o:Other|n:You|All}!')
426
+ I18n.t('hi', :gender => 'm', :locale => :xx, :inflector_raises => true)
427
+ end
301
428
 
429
+ I18n.backend = Backend.new
430
+ assert_raise I18n::BadInflectionKind do
431
+ store_translations(:xx, :i18n => { :inflections => { :@gender => 'something' }})
432
+ end
433
+ I18n.backend = Backend.new
434
+ store_translations(:xx, 'hi' => '@gender+tense{m+now:~|f+past:she was}')
435
+ assert_equal '', I18n.t('hi', :gender => :s, :@gender => :s, :locale => :xx)
436
+ assert_raise I18n::BadInflectionToken do
437
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { :sb => '@', :d=>'1'}}})
438
+ end
439
+ I18n.backend = Backend.new
440
+ assert_raise I18n::BadInflectionToken do
441
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { :sa => nil, :d=>'1'}}})
442
+ end
443
+ I18n.backend = Backend.new
444
+ assert_raise I18n::BadInflectionToken do
445
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { '' => 'a', :d=>'1'}}})
446
+ end
447
+ ['@',',','cos,cos','@cos+cos','+','cos!cos',':','cos:',':cos','cos:cos','!d'].each do |token|
448
+ I18n.backend = Backend.new
449
+ assert_raise I18n::BadInflectionToken do
450
+ store_translations(:xx, :i18n => { :inflections => { :@gender => { token.to_sym => 'a', :d=>'1' }}})
451
+ end
452
+ end
453
+ ['@',',','inflector_something','default','cos,cos','@cos+cos','+','cos!cos',':','cos:',':cos','cos:cos','!d'].each do |kind|
454
+ I18n.backend = Backend.new
455
+ assert_raise I18n::BadInflectionKind do
456
+ store_translations(:xx, :i18n => { :inflections => { kind.to_sym => { :s => 'a', :d=>'1' }}})
457
+ end
458
+ end
302
459
  end
303
460
 
304
461
  test "inflector inflected_locales: lists languages that support inflection" do
@@ -648,7 +805,7 @@ class I18nInflectorTest < Test::Unit::TestCase
648
805
  assert_equal "male", I18n.inflector.token_description(:m, :xx)
649
806
  I18n.locale = :xx
650
807
  assert_equal "male", I18n.inflector.token_description(:m)
651
- assert_equal nil, I18n.inflector.token_description(:nonexistent, :xx)
808
+ assert_equal nil, I18n.inflector.token_description(:vnonexistent, :xx)
652
809
  assert_equal "neuter", I18n.inflector.token_description(:neutral, :xx)
653
810
  end
654
811
 
@@ -656,7 +813,7 @@ class I18nInflectorTest < Test::Unit::TestCase
656
813
  assert_equal "male", I18n.inflector.strict.token_description(:m, :gender, :xx)
657
814
  I18n.locale = :xx
658
815
  assert_equal "male", I18n.inflector.strict.token_description(:m, :gender)
659
- assert_equal nil, I18n.inflector.strict.token_description(:nonexistent, :gender, :xx)
816
+ assert_equal nil, I18n.inflector.strict.token_description(:bnonexistent, :gender, :xx)
660
817
  assert_equal "neuter", I18n.inflector.strict.token_description(:neutral, :gender, :xx)
661
818
  end
662
819
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 2
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 2.1.0
9
+ version: 2.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - "Pawe\xC5\x82 Wilk"
@@ -34,7 +34,7 @@ cert_chain:
34
34
  NK3TIZaPCh1S2/ES6wXNvjQ+5EnEEL9j/pSEop9DYEBPaM2WDVR5i0jJTAaRWw==
35
35
  -----END CERTIFICATE-----
36
36
 
37
- date: 2011-01-27 00:00:00 +01:00
37
+ date: 2011-02-09 00:00:00 +01:00
38
38
  default_executable:
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
@@ -173,10 +173,13 @@ files:
173
173
  - lib/i18n-inflector/api.rb
174
174
  - lib/i18n-inflector/api_strict.rb
175
175
  - lib/i18n-inflector/backend.rb
176
+ - lib/i18n-inflector/config.rb
176
177
  - lib/i18n-inflector/errors.rb
178
+ - lib/i18n-inflector/hset.rb
177
179
  - lib/i18n-inflector/inflection_data.rb
178
180
  - lib/i18n-inflector/inflection_data_strict.rb
179
181
  - lib/i18n-inflector/inflector.rb
182
+ - lib/i18n-inflector/interpolate.rb
180
183
  - lib/i18n-inflector/lazy_enum.rb
181
184
  - lib/i18n-inflector/long_comments.rb
182
185
  - lib/i18n-inflector/options.rb
@@ -199,7 +202,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
199
202
  requirements:
200
203
  - - ">="
201
204
  - !ruby/object:Gem::Version
202
- hash: 3836781751216313437
205
+ hash: -1312043178377028386
203
206
  segments:
204
207
  - 0
205
208
  version: "0"
metadata.gz.sig CHANGED
Binary file