i18n 1.0.1 → 1.6.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -13
  3. data/lib/i18n.rb +53 -27
  4. data/lib/i18n/backend.rb +1 -0
  5. data/lib/i18n/backend/base.rb +36 -9
  6. data/lib/i18n/backend/cache.rb +2 -5
  7. data/lib/i18n/backend/cache_file.rb +36 -0
  8. data/lib/i18n/backend/chain.rb +28 -0
  9. data/lib/i18n/backend/gettext.rb +2 -0
  10. data/lib/i18n/backend/key_value.rb +27 -0
  11. data/lib/i18n/backend/memoize.rb +6 -0
  12. data/lib/i18n/backend/simple.rb +22 -6
  13. data/lib/i18n/config.rb +17 -1
  14. data/lib/i18n/core_ext/hash.rb +42 -24
  15. data/lib/i18n/exceptions.rb +20 -15
  16. data/lib/i18n/interpolate/ruby.rb +5 -3
  17. data/lib/i18n/locale/fallbacks.rb +1 -1
  18. data/lib/i18n/tests/interpolation.rb +1 -1
  19. data/lib/i18n/tests/localization/date.rb +28 -6
  20. data/lib/i18n/tests/localization/date_time.rb +27 -6
  21. data/lib/i18n/tests/localization/time.rb +26 -4
  22. data/lib/i18n/version.rb +1 -1
  23. metadata +24 -58
  24. data/gemfiles/Gemfile.rails-3.2.x +0 -10
  25. data/gemfiles/Gemfile.rails-4.0.x +0 -10
  26. data/gemfiles/Gemfile.rails-4.1.x +0 -10
  27. data/gemfiles/Gemfile.rails-4.2.x +0 -10
  28. data/gemfiles/Gemfile.rails-5.0.x +0 -10
  29. data/gemfiles/Gemfile.rails-5.1.x +0 -10
  30. data/gemfiles/Gemfile.rails-master +0 -10
  31. data/lib/i18n/core_ext/kernel/suppress_warnings.rb +0 -8
  32. data/lib/i18n/core_ext/string/interpolate.rb +0 -9
  33. data/test/api/all_features_test.rb +0 -58
  34. data/test/api/cascade_test.rb +0 -28
  35. data/test/api/chain_test.rb +0 -24
  36. data/test/api/fallbacks_test.rb +0 -30
  37. data/test/api/key_value_test.rb +0 -24
  38. data/test/api/memoize_test.rb +0 -56
  39. data/test/api/override_test.rb +0 -42
  40. data/test/api/pluralization_test.rb +0 -30
  41. data/test/api/simple_test.rb +0 -28
  42. data/test/backend/cache_test.rb +0 -109
  43. data/test/backend/cascade_test.rb +0 -86
  44. data/test/backend/chain_test.rb +0 -122
  45. data/test/backend/exceptions_test.rb +0 -36
  46. data/test/backend/fallbacks_test.rb +0 -219
  47. data/test/backend/interpolation_compiler_test.rb +0 -118
  48. data/test/backend/key_value_test.rb +0 -61
  49. data/test/backend/memoize_test.rb +0 -79
  50. data/test/backend/metadata_test.rb +0 -48
  51. data/test/backend/pluralization_test.rb +0 -45
  52. data/test/backend/simple_test.rb +0 -103
  53. data/test/backend/transliterator_test.rb +0 -84
  54. data/test/core_ext/hash_test.rb +0 -36
  55. data/test/gettext/api_test.rb +0 -214
  56. data/test/gettext/backend_test.rb +0 -92
  57. data/test/i18n/exceptions_test.rb +0 -117
  58. data/test/i18n/gettext_plural_keys_test.rb +0 -20
  59. data/test/i18n/interpolate_test.rb +0 -91
  60. data/test/i18n/load_path_test.rb +0 -34
  61. data/test/i18n/middleware_test.rb +0 -24
  62. data/test/i18n_test.rb +0 -462
  63. data/test/locale/fallbacks_test.rb +0 -133
  64. data/test/locale/tag/rfc4646_test.rb +0 -143
  65. data/test/locale/tag/simple_test.rb +0 -32
  66. data/test/run_all.rb +0 -20
  67. data/test/test_data/locales/de.po +0 -82
  68. data/test/test_data/locales/en.rb +0 -3
  69. data/test/test_data/locales/en.yml +0 -3
  70. data/test/test_data/locales/invalid/empty.yml +0 -0
  71. data/test/test_data/locales/invalid/syntax.yml +0 -4
  72. data/test/test_data/locales/plurals.rb +0 -113
  73. data/test/test_helper.rb +0 -61
@@ -31,6 +31,8 @@ module I18n
31
31
  # Without it strings containing periods (".") will not be translated.
32
32
 
33
33
  module Gettext
34
+ using I18n::HashRefinements
35
+
34
36
  class PoData < Hash
35
37
  def set_comment(msgid_or_sym, comment)
36
38
  # ignore
@@ -67,6 +67,8 @@ module I18n
67
67
  #
68
68
  # This is useful if you are using a KeyValue backend chained to a Simple backend.
69
69
  class KeyValue
70
+ using I18n::HashRefinements
71
+
70
72
  module Implementation
71
73
  attr_accessor :store
72
74
 
@@ -76,6 +78,10 @@ module I18n
76
78
  @store, @subtrees = store, subtrees
77
79
  end
78
80
 
81
+ def initialized?
82
+ !@store.nil?
83
+ end
84
+
79
85
  def store_translations(locale, data, options = EMPTY_HASH)
80
86
  escape = options.fetch(:escape, true)
81
87
  flatten_translations(locale, data, escape, @subtrees).each do |key, value|
@@ -105,6 +111,26 @@ module I18n
105
111
 
106
112
  protected
107
113
 
114
+ # Queries the translations from the key-value store and converts
115
+ # them into a hash such as the one returned from loading the
116
+ # haml files
117
+ def translations
118
+ @translations = @store.keys.clone.map do |main_key|
119
+ main_value = JSON.decode(@store[main_key])
120
+ main_key.to_s.split(".").reverse.inject(main_value) do |value, key|
121
+ {key.to_sym => value}
122
+ end
123
+ end.inject{|hash, elem| hash.deep_merge!(elem)}.deep_symbolize_keys
124
+ end
125
+
126
+ def init_translations
127
+ # NO OP
128
+ # This call made also inside Simple Backend and accessed by
129
+ # other plugins like I18n-js and babilu and
130
+ # to use it along with the Chain backend we need to
131
+ # provide a uniform API even for protected methods :S
132
+ end
133
+
108
134
  def subtrees?
109
135
  @subtrees
110
136
  end
@@ -127,6 +153,7 @@ module I18n
127
153
  if subtrees?
128
154
  super
129
155
  else
156
+ return entry unless entry.is_a?(Hash)
130
157
  key = pluralization_key(entry, count)
131
158
  entry[key]
132
159
  end
@@ -26,6 +26,12 @@ module I18n
26
26
  super
27
27
  end
28
28
 
29
+ def eager_load!
30
+ memoized_lookup
31
+ available_locales
32
+ super
33
+ end
34
+
29
35
  protected
30
36
 
31
37
  def lookup(locale, key, scope = nil, options = EMPTY_HASH)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'i18n/backend/base'
4
+
3
5
  module I18n
4
6
  module Backend
5
7
  # A simple backend that reads translations from YAML files and stores them in
@@ -17,6 +19,8 @@ module I18n
17
19
  #
18
20
  # I18n::Backend::Simple.include(I18n::Backend::Pluralization)
19
21
  class Simple
22
+ using I18n::HashRefinements
23
+
20
24
  (class << self; self; end).class_eval { public :include }
21
25
 
22
26
  module Implementation
@@ -59,6 +63,19 @@ module I18n
59
63
  super
60
64
  end
61
65
 
66
+ def eager_load!
67
+ init_translations unless initialized?
68
+ super
69
+ end
70
+
71
+ def translations(do_init: false)
72
+ # To avoid returning empty translations,
73
+ # call `init_translations`
74
+ init_translations if do_init && !initialized?
75
+
76
+ @translations ||= {}
77
+ end
78
+
62
79
  protected
63
80
 
64
81
  def init_translations
@@ -66,10 +83,6 @@ module I18n
66
83
  @initialized = true
67
84
  end
68
85
 
69
- def translations
70
- @translations ||= {}
71
- end
72
-
73
86
  # Looks up a translation from the translations hash. Returns nil if
74
87
  # either key is nil, or locale, scope or key do not exist as a key in the
75
88
  # nested translations hash. Splits keys or scopes containing dots
@@ -80,8 +93,11 @@ module I18n
80
93
  keys = I18n.normalize_keys(locale, key, scope, options[:separator])
81
94
 
82
95
  keys.inject(translations) do |result, _key|
83
- _key = _key.to_sym
84
- return nil unless result.is_a?(Hash) && result.has_key?(_key)
96
+ return nil unless result.is_a?(Hash)
97
+ unless result.has_key?(_key)
98
+ _key = _key.to_s.to_sym
99
+ return nil unless result.has_key?(_key)
100
+ end
85
101
  result = result[_key]
86
102
  result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
87
103
  result
@@ -7,7 +7,7 @@ module I18n
7
7
  # The only configuration value that is not global and scoped to thread is :locale.
8
8
  # It defaults to the default_locale.
9
9
  def locale
10
- defined?(@locale) && @locale ? @locale : default_locale
10
+ defined?(@locale) && @locale != nil ? @locale : default_locale
11
11
  end
12
12
 
13
13
  # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
@@ -145,5 +145,21 @@ module I18n
145
145
  def enforce_available_locales=(enforce_available_locales)
146
146
  @@enforce_available_locales = enforce_available_locales
147
147
  end
148
+
149
+ # Returns the current interpolation patterns. Defaults to
150
+ # I18n::DEFAULT_INTERPOLATION_PATTERNS.
151
+ def interpolation_patterns
152
+ @@interpolation_patterns ||= I18n::DEFAULT_INTERPOLATION_PATTERNS.dup
153
+ end
154
+
155
+ # Sets the current interpolation patterns. Used to set a interpolation
156
+ # patterns.
157
+ #
158
+ # E.g. using {{}} as a placeholder like "{{hello}}, world!":
159
+ #
160
+ # I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/
161
+ def interpolation_patterns=(interpolation_patterns)
162
+ @@interpolation_patterns = interpolation_patterns
163
+ end
148
164
  end
149
165
  end
@@ -1,29 +1,47 @@
1
- class Hash
2
- def slice(*keep_keys)
3
- h = {}
4
- keep_keys.each { |key| h[key] = fetch(key) if has_key?(key) }
5
- h
6
- end unless Hash.method_defined?(:slice)
1
+ module I18n
2
+ module HashRefinements
3
+ refine Hash do
4
+ using I18n::HashRefinements
5
+ def except(*keys)
6
+ dup.except!(*keys)
7
+ end
7
8
 
8
- def except(*less_keys)
9
- slice(*keys - less_keys)
10
- end unless Hash.method_defined?(:except)
9
+ def except!(*keys)
10
+ keys.each { |key| delete(key) }
11
+ self
12
+ end
11
13
 
12
- def deep_symbolize_keys
13
- inject({}) { |result, (key, value)|
14
- value = value.deep_symbolize_keys if value.is_a?(Hash)
15
- result[(key.to_sym rescue key) || key] = value
16
- result
17
- }
18
- end unless Hash.method_defined?(:deep_symbolize_keys)
14
+ def deep_symbolize_keys
15
+ each_with_object({}) do |(key, value), result|
16
+ result[symbolize_key(key)] = deep_symbolize_keys_in_object(value)
17
+ result
18
+ end
19
+ end
19
20
 
20
- # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
21
- MERGER = proc do |key, v1, v2|
22
- Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
21
+ # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
22
+ def deep_merge!(data)
23
+ merger = lambda do |_key, v1, v2|
24
+ Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
25
+ end
26
+ merge!(data, &merger)
27
+ end
28
+
29
+ def symbolize_key(key)
30
+ key.respond_to?(:to_sym) ? key.to_sym : key
31
+ end
32
+
33
+ private
34
+
35
+ def deep_symbolize_keys_in_object(value)
36
+ case value
37
+ when Hash
38
+ value.deep_symbolize_keys
39
+ when Array
40
+ value.map { |e| deep_symbolize_keys_in_object(e) }
41
+ else
42
+ value
43
+ end
44
+ end
45
+ end
23
46
  end
24
-
25
- def deep_merge!(data)
26
- merge!(data, &MERGER)
27
- end unless Hash.method_defined?(:deep_merge!)
28
47
  end
29
-
@@ -3,27 +3,32 @@
3
3
  require 'cgi'
4
4
 
5
5
  module I18n
6
- # Handles exceptions raised in the backend. All exceptions except for
7
- # MissingTranslationData exceptions are re-thrown. When a MissingTranslationData
8
- # was caught the handler returns an error message string containing the key/scope.
9
- # Note that the exception handler is not called when the option :throw was given.
10
6
  class ExceptionHandler
11
- include Module.new {
12
- def call(exception, locale, key, options)
13
- case exception
14
- when MissingTranslation
15
- exception.message
16
- when Exception
17
- raise exception
18
- else
19
- throw :exception, exception
20
- end
7
+ def call(exception, _locale, _key, _options)
8
+ if exception.is_a?(MissingTranslation)
9
+ exception.message
10
+ else
11
+ raise exception
21
12
  end
22
- }
13
+ end
23
14
  end
24
15
 
25
16
  class ArgumentError < ::ArgumentError; end
26
17
 
18
+ class Disabled < ArgumentError
19
+ def initialize(method)
20
+ super(<<~MESSAGE)
21
+ I18n.#{method} is currently disabled, likely because your application is still in its loading phase.
22
+
23
+ This method is meant to display text in the user locale, so calling it before the user locale has
24
+ been set is likely to display text from the wrong locale to some users.
25
+
26
+ If you have a legitimate reason to access i18n data outside of the user flow, you can do so by passing
27
+ the desired locale explictly with the `locale` argument, e.g. `I18n.#{method}(..., locale: :en)`
28
+ MESSAGE
29
+ end
30
+ end
31
+
27
32
  class InvalidLocale < ArgumentError
28
33
  attr_reader :locale
29
34
  def initialize(locale)
@@ -2,11 +2,13 @@
2
2
  # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
3
3
 
4
4
  module I18n
5
- INTERPOLATION_PATTERN = Regexp.union(
5
+ DEFAULT_INTERPOLATION_PATTERNS = [
6
6
  /%%/,
7
7
  /%\{(\w+)\}/, # matches placeholders like "%{foo}"
8
8
  /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
9
- )
9
+ ].freeze
10
+ INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
11
+ deprecate_constant :INTERPOLATION_PATTERN if method_defined? :INTERPOLATION_PATTERN
10
12
 
11
13
  class << self
12
14
  # Return String or raises MissingInterpolationArgument exception.
@@ -18,7 +20,7 @@ module I18n
18
20
  end
19
21
 
20
22
  def interpolate_hash(string, values)
21
- string.gsub(INTERPOLATION_PATTERN) do |match|
23
+ string.gsub(Regexp.union(config.interpolation_patterns)) do |match|
22
24
  if match == '%%'
23
25
  '%'
24
26
  else
@@ -56,7 +56,7 @@ module I18n
56
56
  def initialize(*mappings)
57
57
  @map = {}
58
58
  map(mappings.pop) if mappings.last.is_a?(Hash)
59
- self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings
59
+ self.defaults = mappings.empty? ? [] : mappings
60
60
  end
61
61
 
62
62
  def defaults=(defaults)
@@ -43,7 +43,7 @@ module I18n
43
43
  end
44
44
 
45
45
  test "interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do
46
- assert_nothing_raised(I18n::MissingInterpolationArgument) do
46
+ assert_nothing_raised do
47
47
  assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr')
48
48
  end
49
49
  end
@@ -11,8 +11,7 @@ module I18n
11
11
  end
12
12
 
13
13
  test "localize Date: given the short format it uses it" do
14
- # TODO should be Mrz, shouldn't it?
15
- assert_equal '01. Mar', I18n.l(@date, :format => :short, :locale => :de)
14
+ assert_equal '01. Mär', I18n.l(@date, :format => :short, :locale => :de)
16
15
  end
17
16
 
18
17
  test "localize Date: given the long format it uses it" do
@@ -27,17 +26,40 @@ module I18n
27
26
  assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de)
28
27
  end
29
28
 
29
+ test "localize Date: given a uppercased day name format it returns the correct day name in upcase" do
30
+ assert_equal 'samstag'.upcase, I18n.l(@date, :format => '%^A', :locale => :de)
31
+ end
32
+
30
33
  test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do
31
34
  assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de)
32
35
  end
33
36
 
37
+ test "localize Date: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
38
+ assert_equal 'sa'.upcase, I18n.l(@date, :format => '%^a', :locale => :de)
39
+ end
40
+
34
41
  test "localize Date: given a month name format it returns the correct month name" do
35
42
  assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de)
36
43
  end
37
44
 
45
+ test "localize Date: given a uppercased month name format it returns the correct month name in upcase" do
46
+ assert_equal 'märz'.upcase, I18n.l(@date, :format => '%^B', :locale => :de)
47
+ end
48
+
38
49
  test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do
39
- # TODO should be Mrz, shouldn't it?
40
- assert_equal 'Mar', I18n.l(@date, :format => '%b', :locale => :de)
50
+ assert_equal 'Mär', I18n.l(@date, :format => '%b', :locale => :de)
51
+ end
52
+
53
+ test "localize Date: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
54
+ assert_equal 'mär'.upcase, I18n.l(@date, :format => '%^b', :locale => :de)
55
+ end
56
+
57
+ test "localize Date: given a date format with the month name upcased it returns the correct value" do
58
+ assert_equal '1. FEBRUAR 2008', I18n.l(::Date.new(2008, 2, 1), :format => "%-d. %^B %Y", :locale => :de)
59
+ end
60
+
61
+ test "localize Date: given missing translations it returns the correct error message" do
62
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@date, :format => '%b', :locale => :fr)
41
63
  end
42
64
 
43
65
  test "localize Date: given an unknown format it does not fail" do
@@ -46,7 +68,7 @@ module I18n
46
68
 
47
69
  test "localize Date: does not modify the options hash" do
48
70
  options = { :format => '%b', :locale => :de }
49
- assert_equal 'Mar', I18n.l(@date, options)
71
+ assert_equal 'Mär', I18n.l(@date, options)
50
72
  assert_equal({ :format => '%b', :locale => :de }, options)
51
73
  assert_nothing_raised { I18n.l(@date, options.freeze) }
52
74
  end
@@ -85,7 +107,7 @@ module I18n
85
107
  :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
86
108
  :abbr_day_names => %w(So Mo Di Mi Do Fr Sa),
87
109
  :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
88
- :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
110
+ :abbr_month_names => %w(Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
89
111
  }
90
112
  }
91
113
  end
@@ -12,8 +12,7 @@ module I18n
12
12
  end
13
13
 
14
14
  test "localize DateTime: given the short format it uses it" do
15
- # TODO should be Mrz, shouldn't it?
16
- assert_equal '01. Mar 06:00', I18n.l(@datetime, :format => :short, :locale => :de)
15
+ assert_equal '01. Mär 06:00', I18n.l(@datetime, :format => :short, :locale => :de)
17
16
  end
18
17
 
19
18
  test "localize DateTime: given the long format it uses it" do
@@ -21,25 +20,47 @@ module I18n
21
20
  end
22
21
 
23
22
  test "localize DateTime: given the default format it uses it" do
24
- # TODO should be Mrz, shouldn't it?
25
- assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
23
+ assert_equal 'Sa, 01. Mär 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
26
24
  end
27
25
 
28
26
  test "localize DateTime: given a day name format it returns the correct day name" do
29
27
  assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de)
30
28
  end
31
29
 
30
+ test "localize DateTime: given a uppercased day name format it returns the correct day name in upcase" do
31
+ assert_equal 'samstag'.upcase, I18n.l(@datetime, :format => '%^A', :locale => :de)
32
+ end
33
+
32
34
  test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do
33
35
  assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de)
34
36
  end
35
37
 
38
+ test "localize DateTime: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
39
+ assert_equal 'sa'.upcase, I18n.l(@datetime, :format => '%^a', :locale => :de)
40
+ end
41
+
36
42
  test "localize DateTime: given a month name format it returns the correct month name" do
37
43
  assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de)
38
44
  end
39
45
 
46
+ test "localize DateTime: given a uppercased month name format it returns the correct month name in upcase" do
47
+ assert_equal 'märz'.upcase, I18n.l(@datetime, :format => '%^B', :locale => :de)
48
+ end
49
+
40
50
  test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do
41
- # TODO should be Mrz, shouldn't it?
42
- assert_equal 'Mar', I18n.l(@datetime, :format => '%b', :locale => :de)
51
+ assert_equal 'Mär', I18n.l(@datetime, :format => '%b', :locale => :de)
52
+ end
53
+
54
+ test "localize DateTime: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
55
+ assert_equal 'mär'.upcase, I18n.l(@datetime, :format => '%^b', :locale => :de)
56
+ end
57
+
58
+ test "localize DateTime: given a date format with the month name upcased it returns the correct value" do
59
+ assert_equal '1. FEBRUAR 2008', I18n.l(::DateTime.new(2008, 2, 1, 6), :format => "%-d. %^B %Y", :locale => :de)
60
+ end
61
+
62
+ test "localize DateTime: given missing translations it returns the correct error message" do
63
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@datetime, :format => '%b', :locale => :fr)
43
64
  end
44
65
 
45
66
  test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do