activesupport 2.3.5 → 2.3.6.pre

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

Potentially problematic release.


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

Files changed (121) hide show
  1. data/CHANGELOG +23 -0
  2. data/lib/active_support.rb +1 -0
  3. data/lib/active_support/core_ext/date_time/conversions.rb +14 -3
  4. data/lib/active_support/core_ext/enumerable.rb +6 -0
  5. data/lib/active_support/core_ext/file/atomic.rb +2 -1
  6. data/lib/active_support/core_ext/numeric/conversions.rb +2 -2
  7. data/lib/active_support/core_ext/object.rb +1 -0
  8. data/lib/active_support/core_ext/object/metaclass.rb +6 -5
  9. data/lib/active_support/core_ext/object/singleton_class.rb +13 -0
  10. data/lib/active_support/core_ext/string.rb +0 -1
  11. data/lib/active_support/core_ext/string/output_safety.rb +148 -44
  12. data/lib/active_support/core_ext/time/calculations.rb +1 -1
  13. data/lib/active_support/inflector.rb +1 -1
  14. data/lib/active_support/json/backends/yajl.rb +40 -0
  15. data/lib/active_support/json/decoding.rb +16 -1
  16. data/lib/active_support/json/encoding.rb +11 -2
  17. data/lib/active_support/ordered_hash.rb +24 -1
  18. data/lib/active_support/vendor.rb +10 -2
  19. data/lib/active_support/vendor/i18n-0.3.3/CHANGELOG.textile +76 -0
  20. data/lib/active_support/vendor/{i18n-0.1.3 → i18n-0.3.3}/MIT-LICENSE +0 -0
  21. data/lib/active_support/vendor/i18n-0.3.3/README.textile +81 -0
  22. data/lib/active_support/vendor/i18n-0.3.3/Rakefile +24 -0
  23. data/lib/active_support/vendor/i18n-0.3.3/benchmark/example.yml +144 -0
  24. data/lib/active_support/vendor/i18n-0.3.3/benchmark/run.rb +71 -0
  25. data/lib/active_support/vendor/i18n-0.3.3/contributors.txt +17 -0
  26. data/lib/active_support/vendor/i18n-0.3.3/i18n.gemspec +165 -0
  27. data/lib/active_support/vendor/i18n-0.3.3/init.rb +1 -0
  28. data/lib/active_support/vendor/{i18n-0.1.3 → i18n-0.3.3}/lib/i18n.rb +99 -21
  29. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend.rb +17 -0
  30. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record.rb +70 -0
  31. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record/missing.rb +67 -0
  32. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record/store_procs.rb +38 -0
  33. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/active_record/translation.rb +83 -0
  34. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/base.rb +259 -0
  35. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/cache.rb +75 -0
  36. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/cascade.rb +44 -0
  37. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/chain.rb +74 -0
  38. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/fallbacks.rb +52 -0
  39. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/fast.rb +68 -0
  40. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/gettext.rb +75 -0
  41. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/helpers.rb +80 -0
  42. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/interpolation_compiler.rb +119 -0
  43. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/metadata.rb +73 -0
  44. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/pluralization.rb +57 -0
  45. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/backend/simple.rb +22 -0
  46. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/core_ext/object/meta_class.rb +5 -0
  47. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/core_ext/string/interpolate.rb +99 -0
  48. data/lib/active_support/vendor/{i18n-0.1.3 → i18n-0.3.3}/lib/i18n/exceptions.rb +14 -6
  49. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/gettext.rb +25 -0
  50. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/helpers.rb +5 -0
  51. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/helpers/gettext.rb +64 -0
  52. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale.rb +6 -0
  53. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/fallbacks.rb +98 -0
  54. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag.rb +28 -0
  55. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag/parents.rb +24 -0
  56. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag/rfc4646.rb +76 -0
  57. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/locale/tag/simple.rb +41 -0
  58. data/lib/active_support/vendor/i18n-0.3.3/lib/i18n/version.rb +3 -0
  59. data/lib/active_support/vendor/i18n-0.3.3/test/all.rb +8 -0
  60. data/lib/active_support/vendor/i18n-0.3.3/test/api/basics.rb +15 -0
  61. data/lib/active_support/vendor/i18n-0.3.3/test/api/defaults.rb +40 -0
  62. data/lib/active_support/vendor/i18n-0.3.3/test/api/interpolation.rb +92 -0
  63. data/lib/active_support/vendor/i18n-0.3.3/test/api/link.rb +55 -0
  64. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/date.rb +91 -0
  65. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/date_time.rb +90 -0
  66. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/procs.rb +54 -0
  67. data/lib/active_support/vendor/i18n-0.3.3/test/api/localization/time.rb +84 -0
  68. data/lib/active_support/vendor/i18n-0.3.3/test/api/lookup.rb +45 -0
  69. data/lib/active_support/vendor/i18n-0.3.3/test/api/pluralization.rb +35 -0
  70. data/lib/active_support/vendor/i18n-0.3.3/test/api/procs.rb +40 -0
  71. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/active_record_test.rb +29 -0
  72. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/all_features_test.rb +40 -0
  73. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/cascade_test.rb +31 -0
  74. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/chain_test.rb +26 -0
  75. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/fallbacks_test.rb +33 -0
  76. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/fast_test.rb +31 -0
  77. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/pluralization_test.rb +33 -0
  78. data/lib/active_support/vendor/i18n-0.3.3/test/cases/api/simple_test.rb +21 -0
  79. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/active_record/missing_test.rb +60 -0
  80. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/active_record_test.rb +52 -0
  81. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/cache_test.rb +72 -0
  82. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/cascade_test.rb +66 -0
  83. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/chain_test.rb +64 -0
  84. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/fallbacks_test.rb +57 -0
  85. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/fast_test.rb +50 -0
  86. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/helpers_test.rb +26 -0
  87. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/interpolation_compiler_test.rb +107 -0
  88. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/metadata_test.rb +67 -0
  89. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/pluralization_test.rb +43 -0
  90. data/lib/active_support/vendor/i18n-0.3.3/test/cases/backend/simple_test.rb +77 -0
  91. data/lib/active_support/vendor/i18n-0.3.3/test/cases/core_ext/string/interpolate_test.rb +94 -0
  92. data/lib/active_support/vendor/i18n-0.3.3/test/cases/gettext/api_test.rb +201 -0
  93. data/lib/active_support/vendor/i18n-0.3.3/test/cases/gettext/backend_test.rb +91 -0
  94. data/lib/active_support/vendor/{i18n-0.1.3/test → i18n-0.3.3/test/cases}/i18n_exceptions_test.rb +8 -10
  95. data/lib/active_support/vendor/i18n-0.3.3/test/cases/i18n_load_path_test.rb +23 -0
  96. data/lib/active_support/vendor/i18n-0.3.3/test/cases/i18n_test.rb +172 -0
  97. data/lib/active_support/vendor/i18n-0.3.3/test/cases/locale/fallbacks_test.rb +126 -0
  98. data/lib/active_support/vendor/i18n-0.3.3/test/cases/locale/tag/rfc4646_test.rb +143 -0
  99. data/lib/active_support/vendor/i18n-0.3.3/test/cases/locale/tag/simple_test.rb +33 -0
  100. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/de.po +72 -0
  101. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/en.rb +3 -0
  102. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/en.yml +3 -0
  103. data/lib/active_support/vendor/i18n-0.3.3/test/fixtures/locales/plurals.rb +113 -0
  104. data/lib/active_support/vendor/i18n-0.3.3/test/test_helper.rb +100 -0
  105. data/lib/active_support/vendor/i18n-0.3.3/vendor/po_parser.rb +329 -0
  106. data/lib/active_support/version.rb +1 -1
  107. data/lib/active_support/whiny_nil.rb +1 -1
  108. data/lib/active_support/xml_mini/libxml.rb +23 -83
  109. data/lib/active_support/xml_mini/libxmlsax.rb +74 -0
  110. data/lib/active_support/xml_mini/nokogiri.rb +25 -22
  111. data/lib/active_support/xml_mini/nokogirisax.rb +73 -0
  112. metadata +108 -20
  113. data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
  114. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
  115. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
  116. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -214
  117. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
  118. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
  119. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
  120. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
  121. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
@@ -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, :separator => separator)
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
@@ -0,0 +1,6 @@
1
+ module I18n
2
+ module Locale
3
+ autoload :Fallbacks, 'i18n/locale/fallbacks'
4
+ autoload :Tag, 'i18n/locale/tag'
5
+ end
6
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module I18n
2
+ VERSION = "0.3.3"
3
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ dir = File.dirname(__FILE__)
4
+ $LOAD_PATH.unshift(dir)
5
+
6
+ Dir["#{dir}/**/*_test.rb"].sort.each do |file|
7
+ require file.sub(/^#{dir}\/(.*)\.rb$/, '\1')
8
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Tests
4
+ module Api
5
+ module Basics
6
+ def test_available_locales
7
+ store_translations('de', :foo => 'bar')
8
+ store_translations('en', :foo => 'foo')
9
+
10
+ assert I18n.available_locales.include?(:de)
11
+ assert I18n.available_locales.include?(:en)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Tests
4
+ module Api
5
+ module Defaults
6
+ def setup
7
+ super
8
+ store_translations(:foo => { :bar => 'bar', :baz => 'baz' })
9
+ end
10
+
11
+ define_method "test defaults: given nil as a key it returns the given default" do
12
+ assert_equal 'default', I18n.t(nil, :default => 'default')
13
+ end
14
+
15
+ define_method "test defaults: given a symbol as a default it translates the symbol" do
16
+ assert_equal 'bar', I18n.t(nil, :default => :'foo.bar')
17
+ end
18
+
19
+ define_method "test defaults: given a symbol as a default and a scope it stays inside the scope when looking up the symbol" do
20
+ assert_equal 'bar', I18n.t(:missing, :default => :bar, :scope => :foo)
21
+ end
22
+
23
+ define_method "test defaults: given an array as a default it returns the first match" do
24
+ assert_equal 'bar', I18n.t(:does_not_exist, :default => [:does_not_exist_2, :'foo.bar'])
25
+ end
26
+
27
+ define_method "test defaults: given an array of missing keys it raises a MissingTranslationData exception" do
28
+ assert_raises I18n::MissingTranslationData do
29
+ I18n.t(:does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3], :raise => true)
30
+ end
31
+ end
32
+
33
+ define_method "test defaults: using a custom scope separator" do
34
+ # data must have been stored using the custom separator when using the ActiveRecord backend
35
+ I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' })
36
+ assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|')
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ module Tests
4
+ module Api
5
+ module Interpolation
6
+ def interpolate(*args)
7
+ options = args.last.is_a?(Hash) ? args.pop : {}
8
+ key = args.pop
9
+ I18n.backend.translate('en', key, options)
10
+ end
11
+
12
+ define_method "test interpolation: given no values it does not alter the string" do
13
+ assert_equal 'Hi {{name}}!', interpolate(:default => 'Hi {{name}}!')
14
+ end
15
+
16
+ define_method "test interpolation: given values it interpolates them into the string" do
17
+ assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => 'David')
18
+ end
19
+
20
+ define_method "test interpolation: given a nil value it still interpolates it into the string" do
21
+ assert_equal 'Hi !', interpolate(:default => 'Hi {{name}}!', :name => nil)
22
+ end
23
+
24
+ define_method "test interpolation: given a lambda as a value it calls it if the string contains the key" do
25
+ assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => lambda { |*args| 'David' })
26
+ end
27
+
28
+ define_method "test interpolation: given a lambda as a value it does not call it if the string does not contain the key" do
29
+ assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) }
30
+ end
31
+
32
+ define_method "test interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do
33
+ assert_raises(I18n::MissingInterpolationArgument) do
34
+ interpolate(:default => '{{foo}}', :bar => 'bar')
35
+ end
36
+ end
37
+
38
+ define_method "test interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do
39
+ assert_nothing_raised(I18n::MissingInterpolationArgument) do
40
+ assert_equal 'Barr {{foo}}', interpolate(:default => '{{bar}} \{{foo}}', :bar => 'Barr')
41
+ end
42
+ end
43
+
44
+ define_method "test interpolation: it does not change the original, stored translation string" do
45
+ I18n.backend.store_translations(:en, :interpolate => 'Hi {{name}}!')
46
+ assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David')
47
+ assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda')
48
+ end
49
+
50
+ define_method "test interpolation: works with Ruby 1.9 syntax" do
51
+ assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
52
+ end
53
+
54
+ define_method "test interpolation: given the translation is in utf-8 it still works" do
55
+ assert_equal 'Häi David!', interpolate(:default => 'Häi {{name}}!', :name => 'David')
56
+ end
57
+
58
+ define_method "test interpolation: given the value is in utf-8 it still works" do
59
+ assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi {{name}}!', :name => 'ゆきひろ')
60
+ end
61
+
62
+ define_method "test interpolation: given the translation and the value are in utf-8 it still works" do
63
+ assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、{{name}}さん!', :name => 'ゆきひろ')
64
+ end
65
+
66
+ if Kernel.const_defined?(:Encoding)
67
+ define_method "test interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do
68
+ assert_raises(Encoding::CompatibilityError) do
69
+ interpolate(:default => euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
70
+ end
71
+ end
72
+
73
+ # define_method "test interpolation: given a utf-8 translation and a euc-jp value it returns a translation in euc-jp" do
74
+ # assert_equal euc_jp('Hi ゆきひろ!'), interpolate(:default => 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
75
+ # end
76
+ #
77
+ # TODO should better explain how this relates to the test above with the simpler utf-8 default string
78
+ define_method "test interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do
79
+ assert_raises(Encoding::CompatibilityError) do
80
+ interpolate(:default => 'こんにちは、{{name}}さん!', :name => euc_jp('ゆきひろ'))
81
+ end
82
+ end
83
+ end
84
+
85
+ define_method "test interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do
86
+ assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{default}}', :foo => :bar) }
87
+ assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{scope}}', :foo => :bar) }
88
+ assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '{{separator}}', :foo => :bar) }
89
+ end
90
+ end
91
+ end
92
+ end