r18n-core 3.2.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +39 -33
  3. data/lib/r18n-core.rb +29 -15
  4. data/lib/r18n-core/filter_list.rb +15 -10
  5. data/lib/r18n-core/filters.rb +22 -26
  6. data/lib/r18n-core/helpers.rb +2 -2
  7. data/lib/r18n-core/i18n.rb +61 -59
  8. data/lib/r18n-core/locale.rb +120 -97
  9. data/{locales → lib/r18n-core/locales}/af.rb +12 -8
  10. data/lib/r18n-core/locales/az.rb +38 -0
  11. data/lib/r18n-core/locales/bg.rb +29 -0
  12. data/{locales → lib/r18n-core/locales}/ca.rb +9 -6
  13. data/{locales → lib/r18n-core/locales}/cs.rb +11 -7
  14. data/lib/r18n-core/locales/cy.rb +50 -0
  15. data/{locales → lib/r18n-core/locales}/da.rb +10 -7
  16. data/lib/r18n-core/locales/de.rb +33 -0
  17. data/{locales → lib/r18n-core/locales}/en-au.rb +1 -1
  18. data/{locales → lib/r18n-core/locales}/en-gb.rb +1 -1
  19. data/{locales → lib/r18n-core/locales}/en-us.rb +2 -1
  20. data/{locales → lib/r18n-core/locales}/en.rb +8 -5
  21. data/{locales → lib/r18n-core/locales}/eo.rb +5 -3
  22. data/lib/r18n-core/locales/es-cl.rb +16 -0
  23. data/{locales → lib/r18n-core/locales}/es-us.rb +4 -3
  24. data/{locales → lib/r18n-core/locales}/es.rb +5 -3
  25. data/{locales → lib/r18n-core/locales}/fa.rb +1 -1
  26. data/lib/r18n-core/locales/fi.rb +39 -0
  27. data/{locales → lib/r18n-core/locales}/fr.rb +10 -6
  28. data/{locales → lib/r18n-core/locales}/gl.rb +5 -3
  29. data/{locales → lib/r18n-core/locales}/hr.rb +8 -5
  30. data/{locales → lib/r18n-core/locales}/hu.rb +8 -5
  31. data/{locales → lib/r18n-core/locales}/id.rb +8 -4
  32. data/{locales → lib/r18n-core/locales}/it.rb +8 -5
  33. data/{locales → lib/r18n-core/locales}/ja.rb +4 -3
  34. data/{locales → lib/r18n-core/locales}/kk.rb +11 -7
  35. data/{locales → lib/r18n-core/locales}/ko.rb +0 -0
  36. data/lib/r18n-core/locales/lv.rb +46 -0
  37. data/lib/r18n-core/locales/mn.rb +30 -0
  38. data/{locales → lib/r18n-core/locales}/nb.rb +5 -3
  39. data/{locales → lib/r18n-core/locales}/nl.rb +10 -7
  40. data/{locales → lib/r18n-core/locales}/no.rb +0 -0
  41. data/lib/r18n-core/locales/pl.rb +45 -0
  42. data/{locales → lib/r18n-core/locales}/pt-br.rb +1 -1
  43. data/lib/r18n-core/locales/pt.rb +35 -0
  44. data/lib/r18n-core/locales/ru.rb +46 -0
  45. data/{locales → lib/r18n-core/locales}/sk.rb +10 -6
  46. data/{locales → lib/r18n-core/locales}/sr-latn.rb +5 -3
  47. data/{locales → lib/r18n-core/locales}/sv-se.rb +6 -4
  48. data/lib/r18n-core/locales/th.rb +41 -0
  49. data/{locales → lib/r18n-core/locales}/tr.rb +5 -4
  50. data/lib/r18n-core/locales/uk.rb +31 -0
  51. data/{locales → lib/r18n-core/locales}/vi.rb +11 -7
  52. data/{locales → lib/r18n-core/locales}/zh-cn.rb +1 -1
  53. data/{locales → lib/r18n-core/locales}/zh-tw.rb +3 -3
  54. data/{locales → lib/r18n-core/locales}/zh.rb +4 -3
  55. data/lib/r18n-core/translated.rb +35 -34
  56. data/lib/r18n-core/translated_string.rb +4 -2
  57. data/lib/r18n-core/translation.rb +16 -17
  58. data/lib/r18n-core/unsupported_locale.rb +6 -5
  59. data/lib/r18n-core/untranslated.rb +10 -4
  60. data/lib/r18n-core/utils.rb +1 -14
  61. data/lib/r18n-core/version.rb +1 -1
  62. data/lib/r18n-core/yaml_loader.rb +13 -13
  63. data/lib/r18n-core/yaml_methods.rb +3 -1
  64. data/r18n-core.gemspec +1 -1
  65. data/spec/filters_spec.rb +3 -0
  66. data/spec/i18n_spec.rb +22 -8
  67. data/spec/locale_spec.rb +4 -5
  68. data/spec/locales/af_spec.rb +9 -0
  69. data/spec/locales/en-us_spec.rb +16 -1
  70. data/spec/locales/es-us_spec.rb +11 -0
  71. data/spec/locales/fi_spec.rb +9 -0
  72. data/spec/locales/hu_spec.rb +2 -0
  73. data/spec/locales/id_spec.rb +23 -0
  74. data/spec/locales/vi_spec.rb +4 -3
  75. data/spec/r18n_spec.rb +21 -7
  76. data/spec/spec_helper.rb +0 -7
  77. data/spec/translated_spec.rb +121 -65
  78. data/spec/translation_spec.rb +5 -2
  79. data/spec/translations/with_regions/en-US.yml +0 -0
  80. data/spec/translations/yaml/en-GB.yml +1 -0
  81. data/spec/translations/yaml/en-us.yml +1 -0
  82. data/spec/yaml_loader_spec.rb +4 -2
  83. metadata +64 -50
  84. data/locales/az.rb +0 -34
  85. data/locales/bg.rb +0 -25
  86. data/locales/cy.rb +0 -50
  87. data/locales/de.rb +0 -29
  88. data/locales/fi.rb +0 -35
  89. data/locales/lv.rb +0 -41
  90. data/locales/mn.rb +0 -27
  91. data/locales/pl.rb +0 -40
  92. data/locales/pt.rb +0 -29
  93. data/locales/ru.rb +0 -41
  94. data/locales/th.rb +0 -37
  95. data/locales/uk.rb +0 -27
@@ -28,8 +28,8 @@ module R18n
28
28
  # Path for this translation.
29
29
  attr_reader :path
30
30
 
31
- # Returns a new string object containing a copy of +str+, which translated
32
- # for +path+ to +locale+
31
+ # Returns a new string object containing a copy of `str`, which translated
32
+ # for `path` to `locale`
33
33
  def initialize(value, locale, path, filters = nil)
34
34
  super(value.to_s)
35
35
  @filters = filters
@@ -93,11 +93,13 @@ module R18n
93
93
  # Return untranslated, when user try to go deeper in translation.
94
94
  def method_missing(name, *_params)
95
95
  return super if NON_KEYS_METHODS.include?(name)
96
+
96
97
  get_untranslated(name.to_s)
97
98
  end
98
99
 
99
100
  def respond_to_missing?(name, *args)
100
101
  return super if NON_KEYS_METHODS.include?(name)
102
+
101
103
  true
102
104
  end
103
105
  end
@@ -23,16 +23,16 @@ module R18n
23
23
 
24
24
  # Translation is container of translated messages.
25
25
  #
26
- # You can load several locales and if translation willnt be found in first,
26
+ # You can load several locales and if translation willn't be found in first,
27
27
  # r18n will be search it in next. Use R18n::I18n.new to load translations.
28
28
  #
29
29
  # To get translation value use method with same name. If translation name
30
- # is equal with Object methods (+new+, +to_s+, +methods+) use
31
- # <tt>[name, params…]</tt>. If you want to get pluralizable value, just set
30
+ # is equal with Object methods (`new`, `to_s`, `methods`) use
31
+ # `[name, params…]`. If you want to get pluralizable value, just set
32
32
  # value for pluralization in first argument of method. See samples below.
33
33
  #
34
- # Translated strings will have +locale+ methods, which return Locale or
35
- # UnsupportedLocale, if locale file isnt exists.
34
+ # Translated strings will have `locale` methods, which return Locale or
35
+ # UnsupportedLocale, if locale file isn't exists.
36
36
  #
37
37
  # == Examples
38
38
  # translations/ru.yml
@@ -68,7 +68,7 @@ module R18n
68
68
  # i18n.comments(10) #=> "10 comments"
69
69
  class Translation
70
70
  # This is internal a constructor. To load translation use
71
- # <tt>R18n::I18n.new(locales, translations_dir)</tt>.
71
+ # `R18n::I18n.new(locales, translations_dir)`.
72
72
  def initialize(locale, path = '', options = {})
73
73
  @data = {}
74
74
  @locale = locale
@@ -78,8 +78,8 @@ module R18n
78
78
  merge! options[:translations], options[:locale] if options[:translations]
79
79
  end
80
80
 
81
- # Add another hash with +translations+ for some +locale+. Current data is
82
- # more priority, that new one in +translations+.
81
+ # Add another hash with `translations` for some `locale`. Current data is
82
+ # more priority, that new one in `translations`.
83
83
  def merge!(translations, locale)
84
84
  (translations || {}).each_pair do |name, value|
85
85
  if !@data.key?(name)
@@ -123,28 +123,27 @@ module R18n
123
123
 
124
124
  # Return current translation keys.
125
125
  #
126
- # Deprecated. Use <tt>to_hash.keys</tt>.
126
+ # Deprecated. Use `to_hash.keys`.
127
127
  def translation_keys
128
128
  to_hash.keys
129
129
  end
130
130
 
131
131
  # Return hash of current translation node.
132
132
  def to_hash
133
- Utils.hash_map(@data) do |key, value|
134
- value = value.to_hash if value.is_a? Translation
135
- [key, value]
133
+ @data.transform_values do |value|
134
+ value.is_a?(Translation) ? value.to_hash : value
136
135
  end
137
136
  end
138
137
 
139
- # Return +default+.
138
+ # Return `default`.
140
139
  def |(other)
141
140
  other
142
141
  end
143
142
 
144
- # Return translation with special +name+.
143
+ # Return translation with special `name`.
145
144
  #
146
- # Translation can contain variable part. Just set is as <tt>%1</tt>,
147
- # <tt>%2</tt>, etc in translations file and set values in next +params+.
145
+ # Translation can contain variable part. Just set is as `%1`,
146
+ # `%2`, etc in translations file and set values in next `params`.
148
147
  def [](name, *params)
149
148
  unless [String, Integer, TrueClass, FalseClass]
150
149
  .any? { |klass| name.is_a?(klass) }
@@ -166,7 +165,7 @@ module R18n
166
165
  end
167
166
  alias method_missing []
168
167
 
169
- # Return translation located at +names+.
168
+ # Return translation located at `keys`.
170
169
  # @see Hash#dig
171
170
  def dig(*keys)
172
171
  keys.reduce(self) { |result, key| result[key] }
@@ -24,10 +24,13 @@ module R18n
24
24
  # Locale, to get data and pluralization for unsupported locale.
25
25
  attr_accessor :base
26
26
 
27
- # Create object for unsupported locale with +code+ and load other locale
28
- # data from +base+ locale.
27
+ attr_reader :code, :downcased_code
28
+
29
+ # Create object for unsupported locale with `code` and load other locale
30
+ # data from `base` locale.
29
31
  def initialize(code, _base = nil)
30
32
  @code = code
33
+ @downcased_code = @code.downcase.tr('-', '_').freeze
31
34
  @base = Locale.load(I18n.default) if @code != I18n.default
32
35
  end
33
36
 
@@ -41,9 +44,6 @@ module R18n
41
44
  "Unsupported locale #{@code}"
42
45
  end
43
46
 
44
- # Locale RFC 3066 code.
45
- attr_reader :code
46
-
47
47
  # Locale code as title.
48
48
  def title
49
49
  @code
@@ -57,6 +57,7 @@ module R18n
57
57
  # Proxy to default locale object.
58
58
  def method_missing(name, *params)
59
59
  return super unless @base.respond_to? name
60
+
60
61
  @base.public_send(name, *params)
61
62
  end
62
63
 
@@ -18,7 +18,7 @@
18
18
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  module R18n
21
- # Return if translation isnt exists. Unlike nil, it didnt raise error when
21
+ # Return if translation isn't exists. Unlike nil, it didn't raise error when
22
22
  # you try to access for subtranslations.
23
23
  #
24
24
  # You can set format to print untranslated string by filters. For example:
@@ -37,7 +37,7 @@ module R18n
37
37
  #
38
38
  # R18n::Filters.add(R18n::Untranslated, :hide_untranslated) { '' }
39
39
  class Untranslated
40
- # Path, that isnt in translation.
40
+ # Path, that isn't in translation.
41
41
  attr_reader :untranslated_path
42
42
 
43
43
  # Path, that exists in translation.
@@ -89,12 +89,17 @@ module R18n
89
89
 
90
90
  def respond_to_missing?(name, *args)
91
91
  return super if NON_KEYS_METHODS.include?(name)
92
+
92
93
  true
93
94
  end
94
95
 
95
96
  def [](*params)
96
- Untranslated.new(translated_path, "#{@untranslated_path}.#{params.first}",
97
- @locale, @filters)
97
+ Untranslated.new(
98
+ translated_path,
99
+ "#{@untranslated_path}.#{params.first}",
100
+ @locale,
101
+ @filters
102
+ )
98
103
  end
99
104
 
100
105
  def |(other)
@@ -116,6 +121,7 @@ module R18n
116
121
  return false unless locale == other.locale
117
122
  return false unless translated_path == other.translated_path
118
123
  return false unless untranslated_path == other.untranslated_path
124
+
119
125
  true
120
126
  end
121
127
  end
@@ -20,26 +20,13 @@
20
20
  # Common methods for another R18n code.
21
21
  module R18n
22
22
  module Utils
23
- HTML_ENTRIES = { '&' => '&amp;', '<' => '&lt;', '>' => '&gt;' }.freeze
24
-
25
23
  # Escape HTML entries (<, >, &). Copy from HAML helper.
26
24
  def self.escape_html(content)
27
25
  if defined? ActiveSupport::SafeBuffer
28
26
  ActiveSupport::SafeBuffer.new + content
29
27
  else
30
- content.to_s.gsub(/[><&]/) { |s| HTML_ENTRIES[s] }
31
- end
32
- end
33
-
34
- # Invokes +block+ once for each key and value of +hash+. Creates a new hash
35
- # with the keys and values returned by the +block+.
36
- def self.hash_map(hash, &block)
37
- result = {}
38
- hash.each_pair do |key, val|
39
- new_key, new_value = block.call(key, val)
40
- result[new_key] = new_value
28
+ CGI.escapeHTML content
41
29
  end
42
- result
43
30
  end
44
31
 
45
32
  # Recursively hash merge.
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version of R18n Core
4
4
  module R18n
5
- VERSION = '3.2.0'.freeze unless defined? R18n::VERSION
5
+ VERSION = '4.0.0' unless defined? R18n::VERSION
6
6
  end
@@ -20,73 +20,73 @@
20
20
  module R18n
21
21
  module Loader
22
22
  # Loader for translations in YAML format. Them should have name like
23
- # +en.yml+ (English) or en-US.yml (USA English dialect) with
23
+ # `en.yml` (English) or en-US.yml (USA English dialect) with
24
24
  # language/country code (RFC 3066).
25
25
  #
26
26
  # R18n::I18n.new('en', R18n::Loader::YAML.new('dir/with/translations'))
27
27
  #
28
28
  # YAML loader is default loader, so you can just set constructor parameter
29
- # to <tt>R18n::I18n.new</tt>:
29
+ # to `R18n::I18n.new`:
30
30
  #
31
31
  # R18n::I18n.new('en', 'dir/with/translations')
32
32
  class YAML
33
33
  include ::R18n::YamlMethods
34
34
 
35
- FILE_EXT = 'y{,a}ml'.freeze
35
+ FILE_EXT = 'y{,a}ml'
36
36
 
37
37
  # Dir with translations.
38
38
  attr_reader :dir
39
39
 
40
- # Create new loader for +dir+ with YAML translations.
40
+ # Create new loader for `dir` with YAML translations.
41
41
  def initialize(dir)
42
42
  @dir = File.expand_path(dir)
43
43
  detect_yaml_private_type
44
44
  end
45
45
 
46
- # Array of locales, which has translations in +dir+.
46
+ # `Array` of locales, which has translations in `dir`.
47
47
  def available
48
48
  Dir.glob(File.join(@dir, "**/*.#{FILE_EXT}"))
49
- .map { |i| File.basename(i, '.*') }.uniq
49
+ .map { |i| File.basename(i, '.*').downcase }.uniq
50
50
  .map { |i| R18n.locale(i) }
51
51
  end
52
52
 
53
- # Return Hash with translations for +locale+.
53
+ # Return `Hash` with translations for `locale`.
54
54
  def load(locale)
55
55
  initialize_types
56
56
 
57
57
  translations = {}
58
58
  Dir.glob(
59
- File.join(@dir, "**/#{locale.code.downcase}.#{FILE_EXT}")
59
+ File.join(@dir, "**/#{locale.code}.#{FILE_EXT}"), File::FNM_CASEFOLD
60
60
  ).each do |i|
61
61
  Utils.deep_merge!(translations, ::YAML.load_file(i) || {})
62
62
  end
63
63
  transform(translations)
64
64
  end
65
65
 
66
- # YAML loader with same +dir+ will be have same +hash+.
66
+ # YAML loader with same `dir` will be have same `hash`.
67
67
  def hash
68
68
  self.class.hash + @dir.hash
69
69
  end
70
70
 
71
- # Is another +loader+ load YAML translations from same +dir+.
71
+ # Is another `loader` load YAML translations from same `dir`.
72
72
  def ==(other)
73
73
  self.class == other.class && dir == other.dir
74
74
  end
75
75
 
76
76
  # Wrap YAML private types to Typed.
77
77
  def transform(a_hash)
78
- R18n::Utils.hash_map(a_hash) do |key, value|
78
+ a_hash.transform_values do |value|
79
79
  if value.is_a? Hash
80
80
  value = transform(value)
81
81
  elsif defined?(@private_type_class) &&
82
- value.is_a?(@private_type_class)
82
+ value.is_a?(@private_type_class)
83
83
  v = value.value
84
84
  if v.respond_to?(:force_encoding) && v.encoding != __ENCODING__
85
85
  v = v.force_encoding(__ENCODING__)
86
86
  end
87
87
  value = Typed.new(value.type_id, v)
88
88
  end
89
- [key, value]
89
+ value
90
90
  end
91
91
  end
92
92
  end
@@ -31,9 +31,11 @@ module R18n
31
31
  # Register global types in Psych
32
32
  def initialize_types
33
33
  return unless defined?(Psych)
34
+
34
35
  Filters.by_type.each_key do |type|
35
36
  next unless type.is_a? String
36
- # Yeah, I add R18n’s types to global, send me patch if you really
37
+
38
+ # Yeah, I add R18n's types to global, send me patch if you really
37
39
  # use YAML types too ;).
38
40
  Psych.add_domain_type('yaml.org,2002', type) do |_full_type, value|
39
41
  Typed.new(type, value)
@@ -24,6 +24,6 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.author = 'Andrey Sitnik'
26
26
  s.email = 'andrey@sitnik.ru'
27
- s.homepage = 'https://github.com/ai/r18n'
27
+ s.homepage = 'https://github.com/r18n/r18n'
28
28
  s.license = 'LGPL-3.0'
29
29
  end
@@ -11,6 +11,7 @@ describe R18n::Filters do
11
11
  after do
12
12
  R18n::Filters.defined.each_value do |filter|
13
13
  next if @system.include? filter
14
+
14
15
  R18n::Filters.delete(filter)
15
16
  end
16
17
 
@@ -190,6 +191,7 @@ describe R18n::Filters do
190
191
  )
191
192
  end
192
193
 
194
+ # rubocop:disable Style/FormatStringToken
193
195
  it 'interpolates named variables' do
194
196
  R18n::Filters.off(:named_variables)
195
197
  expect(@i18n.echo(value: 'R18n')).to eq 'Value is %{value}'
@@ -204,6 +206,7 @@ describe R18n::Filters do
204
206
  expect(@i18n.echo2(value: 'R18n')).to eq 'Value2 is R18n'
205
207
  expect(@i18n.echo2).to eq 'Value2 is {{value}}'
206
208
  end
209
+ # rubocop:enable Style/FormatStringToken
207
210
 
208
211
  it 'formats untranslated' do
209
212
  expect(@i18n.in.not.to_s).to eq('in.[not]')
@@ -27,7 +27,7 @@ describe R18n::I18n do
27
27
  i18n = R18n::I18n.new('en', DIR)
28
28
  expect(i18n.locales).to eq([R18n.locale('en')])
29
29
 
30
- i18n = R18n::I18n.new(['ru', 'nolocale-DL'], DIR)
30
+ i18n = R18n::I18n.new(%w[ru nolocale-DL], DIR)
31
31
  expect(i18n.locales).to eq([
32
32
  R18n.locale('ru'),
33
33
  R18n::UnsupportedLocale.new('nolocale-DL'),
@@ -123,6 +123,11 @@ describe R18n::I18n do
123
123
  expect(i18n.two).to eq('Two')
124
124
  end
125
125
 
126
+ it 'loads base translations from parent locale' do
127
+ i18n = R18n::I18n.new('en-US', File.join(TRANSLATIONS, 'with_regions'))
128
+ expect(i18n.save).to eq('Save')
129
+ end
130
+
126
131
  it 'returns available translations' do
127
132
  i18n = R18n::I18n.new('en', DIR)
128
133
  expect(i18n.available_locales).to match_array([
@@ -236,18 +241,27 @@ describe R18n::I18n do
236
241
  expect(i18n.l(-123_456_789)).to eq('−123 456 789')
237
242
  expect(i18n.l(-12_345.67)).to eq('−12 345,67')
238
243
 
239
- time = Time.at(0).utc
240
- expect(i18n.l(time, '%A')).to eq('Четверг')
241
- expect(i18n.l(time, :month)).to eq('Январь')
242
- expect(i18n.l(time, :standard)).to eq('01.01.1970 00:00')
243
- expect(i18n.l(time, :full)).to eq('1 января 1970 00:00')
244
+ time = Time.utc(2014, 5, 6, 7, 8, 9)
245
+ expect(i18n.l(time, '%A'))
246
+ .to eq('Вторник')
247
+ expect(i18n.l(time, :month))
248
+ .to eq('Май')
249
+ expect(i18n.l(time, :standard))
250
+ .to eq('06.05.2014 07:08')
251
+ expect(i18n.l(time, :standard, with_seconds: true))
252
+ .to eq('06.05.2014 07:08:09')
253
+ expect(i18n.l(time, :full))
254
+ .to eq('6 мая 2014 07:08')
255
+ expect(i18n.l(time, :full, with_seconds: true))
256
+ .to eq('6 мая 2014 07:08:09')
244
257
 
245
258
  expect(i18n.l(Date.new(0))).to eq('01.01.0000')
246
259
  end
247
260
 
248
261
  it 'returns marshalizable values' do
249
- i18n = R18n::I18n.new('en', DIR, off_filters: :untranslated,
250
- on_filters: :untranslated_html)
262
+ i18n = R18n::I18n.new(
263
+ 'en', DIR, off_filters: :untranslated, on_filters: :untranslated_html
264
+ )
251
265
  demarsh = Marshal.load(Marshal.dump(i18n.t.one))
252
266
 
253
267
  expect(i18n.t.one).to eq(demarsh)
@@ -8,11 +8,6 @@ describe R18n::Locale do
8
8
  @en = R18n.locale('en')
9
9
  end
10
10
 
11
- it 'returns all available locales' do
12
- expect(R18n::Locale.available.class).to eq(Array)
13
- expect(R18n::Locale.available).not_to be_empty
14
- end
15
-
16
11
  it 'checks is locale exists' do
17
12
  expect(R18n::Locale.exists?('ru')).to be true
18
13
  expect(R18n::Locale.exists?('nolocale')).to be false
@@ -20,6 +15,10 @@ describe R18n::Locale do
20
15
 
21
16
  it 'sets locale properties' do
22
17
  locale_class = Class.new(R18n::Locale) do
18
+ def self.name
19
+ 'Foo'
20
+ end
21
+
23
22
  set one: 1
24
23
  set two: 2
25
24
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe R18n::Locales::Af do
4
+ it 'formats Afrikaans time' do
5
+ af = R18n::I18n.new('af')
6
+ expect(af.l(Time.utc(2009, 5, 1, 6, 7, 8), :standard, with_seconds: true))
7
+ .to eq('01/05/2009, 06:07:08')
8
+ end
9
+ end