i18n 0.5.0beta1 → 0.5.0beta2

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 (62) hide show
  1. data/README.textile +4 -17
  2. data/ci/Gemfile.no-rails +5 -0
  3. data/ci/Gemfile.no-rails.lock +17 -0
  4. data/ci/Gemfile.rails-2.3.x +9 -0
  5. data/ci/Gemfile.rails-2.3.x.lock +26 -0
  6. data/ci/Gemfile.rails-3.x +9 -0
  7. data/ci/Gemfile.rails-3.x.lock +26 -0
  8. data/lib/i18n.rb +4 -8
  9. data/lib/i18n/backend.rb +0 -1
  10. data/lib/i18n/backend/base.rb +4 -32
  11. data/lib/i18n/backend/gettext.rb +3 -3
  12. data/lib/i18n/backend/interpolation_compiler.rb +1 -1
  13. data/lib/i18n/backend/metadata.rb +1 -1
  14. data/lib/i18n/config.rb +1 -1
  15. data/lib/i18n/core_ext/kernel/surpress_warnings.rb +9 -0
  16. data/lib/i18n/core_ext/string/interpolate.rb +0 -96
  17. data/lib/i18n/exceptions.rb +0 -6
  18. data/lib/i18n/interpolate/ruby.rb +31 -0
  19. data/lib/i18n/locale/fallbacks.rb +3 -3
  20. data/lib/i18n/tests/localization/procs.rb +32 -19
  21. data/lib/i18n/tests/localization/time.rb +2 -2
  22. data/lib/i18n/version.rb +1 -1
  23. data/test/all.rb +8 -0
  24. data/test/api/all_features_test.rb +58 -0
  25. data/test/api/cascade_test.rb +28 -0
  26. data/test/api/chain_test.rb +24 -0
  27. data/test/api/fallbacks_test.rb +30 -0
  28. data/test/api/key_value_test.rb +28 -0
  29. data/test/api/memoize_test.rb +60 -0
  30. data/test/api/pluralization_test.rb +30 -0
  31. data/test/api/simple_test.rb +28 -0
  32. data/test/backend/cache_test.rb +83 -0
  33. data/test/backend/cascade_test.rb +85 -0
  34. data/test/backend/chain_test.rb +67 -0
  35. data/test/backend/exceptions_test.rb +23 -0
  36. data/test/backend/fallbacks_test.rb +116 -0
  37. data/test/backend/interpolation_compiler_test.rb +102 -0
  38. data/test/backend/key_value_test.rb +46 -0
  39. data/test/backend/memoize_test.rb +47 -0
  40. data/test/backend/metadata_test.rb +67 -0
  41. data/test/backend/pluralization_test.rb +44 -0
  42. data/test/backend/simple_test.rb +79 -0
  43. data/test/backend/transliterator_test.rb +81 -0
  44. data/test/core_ext/hash_test.rb +30 -0
  45. data/test/gettext/api_test.rb +206 -0
  46. data/test/gettext/backend_test.rb +93 -0
  47. data/test/i18n/exceptions_test.rb +116 -0
  48. data/test/i18n/interpolate_test.rb +60 -0
  49. data/test/i18n/load_path_test.rb +26 -0
  50. data/test/i18n_test.rb +236 -0
  51. data/test/locale/fallbacks_test.rb +124 -0
  52. data/test/locale/tag/rfc4646_test.rb +142 -0
  53. data/test/locale/tag/simple_test.rb +32 -0
  54. data/test/run_all.rb +21 -0
  55. data/test/test_data/locales/de.po +72 -0
  56. data/test/test_data/locales/en.rb +3 -0
  57. data/test/test_data/locales/en.yml +3 -0
  58. data/test/test_data/locales/invalid/empty.yml +1 -0
  59. data/test/test_data/locales/plurals.rb +113 -0
  60. data/test/test_helper.rb +56 -0
  61. metadata +116 -14
  62. data/lib/i18n/backend/cldr.rb +0 -99
@@ -64,25 +64,12 @@ h2. Tests
64
64
  You can run tests both with
65
65
 
66
66
  * `rake test` or just `rake`
67
- * run any test file directly, e.g. `ruby test/api/simple_test.rb`
68
- * run all tests with `ruby test/all.rb`
67
+ * run any test file directly, e.g. `ruby -Ilib -Itest test/api/simple_test.rb`
68
+ * run all tests with `ruby -Ilib -Itest test/all.rb`
69
69
 
70
- You can parametrize the test suite for using different sets of dependencies by
71
- using:
70
+ You can run all tests against all Gemfiles with
72
71
 
73
- .pre `ruby test/all.rb -w DEPENDENCIES`
74
-
75
- ... where DEPENDENCIES is a comma-separated list of:
76
-
77
- * r23 or rails-2.3.x
78
- * r3 or rails-3.x
79
- * no-rails
80
- * sqlite
81
- * mysql
82
-
83
- So, e.g. this would run the test suite against Rails 2.3.x using mysql:
84
-
85
- .pre `ruby test/all.rb -w r23,mysql`
72
+ * `ruby test/run_all.rb`
86
73
 
87
74
  The structure of the test suite is a bit unusual as it uses modules to reuse
88
75
  particular tests in different test cases.
@@ -0,0 +1,5 @@
1
+ source :rubygems
2
+
3
+ gem 'mocha'
4
+ gem 'test_declarative'
5
+
@@ -0,0 +1,17 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ mocha (0.9.9)
5
+ rake
6
+ rake (0.8.7)
7
+ test_declarative (0.0.4)
8
+
9
+ PLATFORMS
10
+ ruby
11
+
12
+ DEPENDENCIES
13
+ mocha
14
+ test_declarative
15
+
16
+ METADATA
17
+ version: 1.0.6
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ gem 'activesupport', '~> 2.3'
4
+ gem 'sqlite3-ruby'
5
+ gem 'mocha'
6
+ gem 'test_declarative'
7
+ gem 'rufus-tokyo'
8
+ gem 'ffi'
9
+
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (2.3.10)
5
+ ffi (0.6.3)
6
+ rake (>= 0.8.7)
7
+ mocha (0.9.9)
8
+ rake
9
+ rake (0.8.7)
10
+ rufus-tokyo (1.0.7)
11
+ sqlite3-ruby (1.3.2)
12
+ test_declarative (0.0.4)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ activesupport (~> 2.3)
19
+ ffi
20
+ mocha
21
+ rufus-tokyo
22
+ sqlite3-ruby
23
+ test_declarative
24
+
25
+ METADATA
26
+ version: 1.0.6
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ gem 'activesupport', '~> 3.0.0'
4
+ gem 'sqlite3-ruby'
5
+ gem 'mocha'
6
+ gem 'test_declarative'
7
+ gem 'rufus-tokyo'
8
+ gem 'ffi'
9
+
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.0.1)
5
+ ffi (0.6.3)
6
+ rake (>= 0.8.7)
7
+ mocha (0.9.9)
8
+ rake
9
+ rake (0.8.7)
10
+ rufus-tokyo (1.0.7)
11
+ sqlite3-ruby (1.3.2)
12
+ test_declarative (0.0.4)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ activesupport (~> 3.0.0)
19
+ ffi
20
+ mocha
21
+ rufus-tokyo
22
+ sqlite3-ruby
23
+ test_declarative
24
+
25
+ METADATA
26
+ version: 1.0.6
@@ -1,13 +1,6 @@
1
- # Authors:: Sven Fuchs (http://www.artweb-design.de),
2
- # Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
3
- # Stephan Soller (http://www.arkanis-development.de/),
4
- # Saimon Moore (http://saimonmoore.net),
5
- # Matt Aimonetti (http://railsontherun.com/)
6
- # Copyright:: Copyright (c) 2008 The Ruby i18n Team
7
- # License:: MIT
8
1
  require 'i18n/version'
9
2
  require 'i18n/exceptions'
10
- require 'i18n/core_ext/string/interpolate'
3
+ require 'i18n/interpolate/ruby.rb'
11
4
 
12
5
  module I18n
13
6
  autoload :Backend, 'i18n/backend'
@@ -16,6 +9,9 @@ module I18n
16
9
  autoload :Locale, 'i18n/locale'
17
10
  autoload :Tests, 'i18n/tests'
18
11
 
12
+ RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback, :format, :cascade, :raise, :rescue_format]
13
+ RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
14
+
19
15
  class << self
20
16
  # Gets I18n configuration object.
21
17
  def config
@@ -5,7 +5,6 @@ module I18n
5
5
  autoload :Cache, 'i18n/backend/cache'
6
6
  autoload :Cascade, 'i18n/backend/cascade'
7
7
  autoload :Chain, 'i18n/backend/chain'
8
- autoload :Cldr, 'i18n/backend/cldr'
9
8
  autoload :Fallbacks, 'i18n/backend/fallbacks'
10
9
  autoload :Flatten, 'i18n/backend/flatten'
11
10
  autoload :Gettext, 'i18n/backend/gettext'
@@ -1,14 +1,12 @@
1
1
  require 'yaml'
2
2
  require 'i18n/core_ext/hash'
3
+ require 'i18n/core_ext/kernel/surpress_warnings'
3
4
 
4
5
  module I18n
5
6
  module Backend
6
7
  module Base
7
8
  include I18n::Backend::Transliterator
8
9
 
9
- RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback]
10
- RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
11
-
12
10
  # Accepts a list of paths to translation files. Loads translations from
13
11
  # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
14
12
  # for details.
@@ -140,34 +138,14 @@ module I18n
140
138
  #
141
139
  # interpolate "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X'
142
140
  # # => "file test.txt opened by %{user}"
143
- #
144
- # Note that you have to double escape the <tt>\\</tt> when you want to escape
145
- # the <tt>{{...}}</tt> key in a string (once for the string and once for the
146
- # interpolation).
147
141
  def interpolate(locale, string, values = {})
148
- return string unless string.is_a?(::String) && !values.empty?
149
-
150
- values.each do |key, value|
151
- value = value.call(values) if interpolate_lambda?(value, string, key)
152
- value = value.to_s unless value.is_a?(::String)
153
- values[key] = value
154
- end
155
-
156
- string % values
157
- rescue KeyError => e
158
- if string =~ RESERVED_KEYS_PATTERN
159
- raise ReservedInterpolationKey.new($1.to_sym, string)
142
+ if string.is_a?(::String) && !values.empty?
143
+ I18n.interpolate(string, values)
160
144
  else
161
- raise MissingInterpolationArgument.new(values, string)
145
+ string
162
146
  end
163
147
  end
164
148
 
165
- # returns true when the given value responds to :call and the key is
166
- # an interpolation placeholder in the given string
167
- def interpolate_lambda?(object, string, key)
168
- object.respond_to?(:call) && string =~ /%\{#{key}\}|%\<#{key}>.*?\d*\.?\d*[bBdiouxXeEfgGcps]\}/
169
- end
170
-
171
149
  # Loads a single translations file by delegating to #load_rb or
172
150
  # #load_yml depending on the file extension and directly merges the
173
151
  # data to the existing translations. Raises I18n::UnknownFileType
@@ -191,12 +169,6 @@ module I18n
191
169
  def load_yml(filename)
192
170
  YAML.load_file(filename)
193
171
  end
194
-
195
- def warn_syntax_deprecation!(locale, string) #:nodoc:
196
- return if @skip_syntax_deprecation
197
- warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\n#{locale} - #{string}\n"
198
- @skip_syntax_deprecation = true
199
- end
200
172
  end
201
173
  end
202
174
  end
@@ -43,8 +43,8 @@ module I18n
43
43
  key, value = normalize_pluralization(locale, key, value) if key.index("\000")
44
44
 
45
45
  parts = key.split('|').reverse
46
- normalized = parts.inject({}) do |normalized, part|
47
- normalized = { part => normalized.empty? ? value : normalized }
46
+ normalized = parts.inject({}) do |_normalized, part|
47
+ { part => _normalized.empty? ? value : _normalized }
48
48
  end
49
49
 
50
50
  result.deep_merge!(normalized)
@@ -62,7 +62,7 @@ module I18n
62
62
  raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect}" if values.size != keys.size
63
63
 
64
64
  result = {}
65
- values.each_with_index { |value, ix| result[keys[ix]] = value }
65
+ values.each_with_index { |_value, ix| result[keys[ix]] = _value }
66
66
  [key, result]
67
67
  end
68
68
 
@@ -61,7 +61,7 @@ module I18n
61
61
 
62
62
  def interpolate_or_raise_missing(key)
63
63
  escaped_key = escape_key_sym(key)
64
- Base::RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key)
64
+ RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key)
65
65
  end
66
66
 
67
67
  def interpolate_key(key)
@@ -38,7 +38,7 @@ module I18n
38
38
  :scope => options[:scope],
39
39
  :default => options[:default],
40
40
  :separator => options[:separator],
41
- :values => options.reject { |name, value| Base::RESERVED_KEYS.include?(name) }
41
+ :values => options.reject { |name, value| RESERVED_KEYS.include?(name) }
42
42
  }
43
43
  with_metadata(metadata) { super }
44
44
  end
@@ -41,7 +41,7 @@ module I18n
41
41
 
42
42
  # Sets the available locales.
43
43
  def available_locales=(locales)
44
- @@available_locales = Array(locales).map {|locale| locale.to_sym}
44
+ @@available_locales = Array(locales).map { |locale| locale.to_sym }
45
45
  @@available_locales = nil if @@available_locales.empty?
46
46
  end
47
47
 
@@ -0,0 +1,9 @@
1
+ module Kernel
2
+ def suppress_warnings
3
+ original_verbosity = $VERBOSE
4
+ $VERBOSE = nil
5
+ result = yield
6
+ $VERBOSE = original_verbosity
7
+ result
8
+ end
9
+ end
@@ -1,96 +0,0 @@
1
- =begin
2
- heavily based on Masao Mutoh's gettext String interpolation extension
3
- http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
4
- Copyright (C) 2005-2009 Masao Mutoh
5
- You may redistribute it and/or modify it under the same license terms as Ruby.
6
- =end
7
-
8
- begin
9
- raise ArgumentError if ("a %{x}" % {:x=>'b'}) != 'a b'
10
- rescue ArgumentError
11
- # KeyError is raised by String#% when the string contains a named placeholder
12
- # that is not contained in the given arguments hash. Ruby 1.9 includes and
13
- # raises this exception natively. We define it to mimic Ruby 1.9's behaviour
14
- # in Ruby 1.8.x
15
- class KeyError < IndexError
16
- def initialize(message = nil)
17
- super(message || "key not found")
18
- end
19
- end unless defined?(KeyError)
20
-
21
- # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
22
- #
23
- # String#% method which accept "named argument". The translator can know
24
- # the meaning of the msgids using "named argument" instead of %s/%d style.
25
- class String
26
- # For older ruby versions, such as ruby-1.8.5
27
- alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'}
28
- alias :interpolate_without_ruby_19_syntax :% # :nodoc:
29
-
30
- INTERPOLATION_PATTERN = Regexp.union(
31
- /%\{(\w+)\}/, # matches placeholders like "%{foo}"
32
- /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
33
- )
34
-
35
- INTERPOLATION_PATTERN_WITH_ESCAPE = Regexp.union(
36
- /%%/,
37
- INTERPOLATION_PATTERN
38
- )
39
-
40
- # % uses self (i.e. the String) as a format specification and returns the
41
- # result of applying it to the given arguments. In other words it interpolates
42
- # the given arguments to the string according to the formats the string
43
- # defines.
44
- #
45
- # There are three ways to use it:
46
- #
47
- # * Using a single argument or Array of arguments.
48
- #
49
- # This is the default behaviour of the String class. See Kernel#sprintf for
50
- # more details about the format string.
51
- #
52
- # Example:
53
- #
54
- # "%d %s" % [1, "message"]
55
- # # => "1 message"
56
- #
57
- # * Using a Hash as an argument and unformatted, named placeholders.
58
- #
59
- # When you pass a Hash as an argument and specify placeholders with %{foo}
60
- # it will interpret the hash values as named arguments.
61
- #
62
- # Example:
63
- #
64
- # "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"}
65
- # # => "Masao Mutoh"
66
- #
67
- # * Using a Hash as an argument and formatted, named placeholders.
68
- #
69
- # When you pass a Hash as an argument and specify placeholders with %<foo>d
70
- # it will interpret the hash values as named arguments and format the value
71
- # according to the formatting instruction appended to the closing >.
72
- #
73
- # Example:
74
- #
75
- # "%<integer>d, %<float>.1f" % { :integer => 10, :float => 43.4 }
76
- # # => "10, 43.3"
77
- def %(args)
78
- if args.kind_of?(Hash)
79
- dup.gsub(INTERPOLATION_PATTERN_WITH_ESCAPE) do |match|
80
- if match == '%%'
81
- '%'
82
- else
83
- key = ($1 || $2).to_sym
84
- raise KeyError unless args.has_key?(key)
85
- $3 ? sprintf("%#{$3}", args[key]) : args[key]
86
- end
87
- end
88
- elsif self =~ INTERPOLATION_PATTERN
89
- raise ArgumentError.new('one hash required')
90
- else
91
- result = gsub(/%([{<])/, '%%\1')
92
- result.send :'interpolate_without_ruby_19_syntax', args
93
- end
94
- end
95
- end
96
- end
@@ -1,9 +1,3 @@
1
- class KeyError < IndexError
2
- def initialize(message = nil)
3
- super(message || "key not found")
4
- end
5
- end unless defined?(KeyError)
6
-
7
1
  module I18n
8
2
  # Handles exceptions raised in the backend. All exceptions except for
9
3
  # MissingTranslationData exceptions are re-raised. When a MissingTranslationData
@@ -0,0 +1,31 @@
1
+ # heavily based on Masao Mutoh's gettext String interpolation extension
2
+ # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
3
+
4
+ module I18n
5
+ INTERPOLATION_PATTERN = Regexp.union(
6
+ /%%/,
7
+ /%\{(\w+)\}/, # matches placeholders like "%{foo}"
8
+ /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
9
+ )
10
+
11
+ class << self
12
+ def interpolate(string, values)
13
+ raise ReservedInterpolationKey.new($1.to_sym, string) if string =~ RESERVED_KEYS_PATTERN
14
+ raise ArgumentError.new('Interpolation values must be a Hash.') unless values.kind_of?(Hash)
15
+ interpolate_hash(string, values)
16
+ end
17
+
18
+ def interpolate_hash(string, values)
19
+ string.gsub(INTERPOLATION_PATTERN) do |match|
20
+ if match == '%%'
21
+ '%'
22
+ else
23
+ key = ($1 || $2).to_sym
24
+ value = values.key?(key) ? values[key] : raise(MissingInterpolationArgument.new(values, string))
25
+ value = value.call(values) if value.respond_to?(:call)
26
+ $3 ? sprintf("%#{$3}", value) : value
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -73,9 +73,9 @@ module I18n
73
73
  def map(mappings)
74
74
  mappings.each do |from, to|
75
75
  from, to = from.to_sym, Array(to)
76
- to.each do |to|
76
+ to.each do |_to|
77
77
  @map[from] ||= []
78
- @map[from] << to.to_sym
78
+ @map[from] << _to.to_sym
79
79
  end
80
80
  end
81
81
  end
@@ -85,7 +85,7 @@ module I18n
85
85
  def compute(tags, include_defaults = true)
86
86
  result = Array(tags).collect do |tag|
87
87
  tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym }
88
- tags.each { |tag| tags += compute(@map[tag]) if @map[tag] }
88
+ tags.each { |_tag| tags += compute(@map[_tag]) if @map[_tag] }
89
89
  tags
90
90
  end.flatten
91
91
  result.push(*defaults) if include_defaults