tater 2.0.4 → 3.0.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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tater.rb +29 -93
  3. data/test/tater_test.rb +25 -12
  4. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51644f41d80e87d20ed43b9e8c6b4797fb7aeb4258c94d5d9f9d7a50eb5ee5c6
4
- data.tar.gz: 1fe43b99fbc2f24cdc342ec4278ff7140ee6b9579dd51d236fcc713907f1455d
3
+ metadata.gz: c34d7058c3566313243c4ccb7b99d967c60bf2e00e091d1fbb66dfbd257e853f
4
+ data.tar.gz: 0a5c1d4df6a34b9953086af0459af4c72cb8d9faf674d3216e1eb9e00aa0e82f
5
5
  SHA512:
6
- metadata.gz: d4c059fdc696d39c489e61d3e53954fe921feaba78055bd5e62c944d45daf10dfa178b76e4e836d326ba61be0dbf7bbec13b63f52b95e13f23da9ca5be4d3b8c
7
- data.tar.gz: 6b12ffa8f2a1186f2de92c9c16bb5c2e1027f93ab5ee2c877dbad297777274b9f4f38882255490db3c555a0dafb129ed876bd784d3a872e07a4e7e9f6e0e24ec
6
+ metadata.gz: ac657b28f3e3421def12e3d0b50bcd895c5d1a1b23de7c97da6bf0e20bc5e0a51e20abf7394ec9e99b2137e9b2261392213f0dc85d2d3b0c598c4e73184d8857
7
+ data.tar.gz: 4b5b32cf7b23a66afcde0a73f129a76d791f62a8efa45a7223204d9e017328796cf528ad8884a2c25a568ea47d3047fff57c4973741aaae20e1e7574350a9068
data/lib/tater.rb CHANGED
@@ -3,91 +3,14 @@ require 'bigdecimal'
3
3
  require 'date'
4
4
  require 'time'
5
5
  require 'yaml'
6
+ require 'tater/utils'
6
7
 
7
8
  # Tater is a internationalization (i18n) and localization (l10n) library
8
9
  # designed for speed and simplicity.
9
10
  class Tater
10
11
  class MissingLocalizationFormat < ArgumentError; end
11
-
12
12
  class UnLocalizableObject < ArgumentError; end
13
13
 
14
- module Utils # :nodoc:
15
- # Merge all the way down.
16
- #
17
- # @param to [Hash]
18
- # The target Hash to merge into.
19
- # @param from [Hash]
20
- # The Hash to copy values from.
21
- # @return [Hash]
22
- def self.deep_merge(to, from)
23
- to.merge(from) do |_key, left, right|
24
- if left.is_a?(Hash) && right.is_a?(Hash)
25
- Utils.deep_merge(left, right)
26
- else
27
- right
28
- end
29
- end
30
- end
31
-
32
- # Transform keys all the way down.
33
- #
34
- # @param hash [Hash]
35
- # The Hash to stringify keys for.
36
- # @return [Hash]
37
- def self.deep_stringify_keys(hash)
38
- hash.transform_keys(&:to_s).transform_values do |value|
39
- if value.is_a?(Hash)
40
- Utils.deep_stringify_keys(value)
41
- else
42
- value
43
- end
44
- end
45
- end
46
-
47
- # Freeze all the way down.
48
- #
49
- # @param hash [Hash]
50
- # @return [Hash]
51
- def self.deep_freeze(hash)
52
- hash.transform_keys(&:freeze).transform_values do |value|
53
- if value.is_a?(Hash)
54
- Utils.deep_freeze(value)
55
- else
56
- value.freeze
57
- end
58
- end.freeze
59
- end
60
-
61
- # Try to interpolate these things, if one of them is a string.
62
- #
63
- # @param string [String]
64
- # The target string to interpolate into.
65
- # @param options [Hash]
66
- # The values to interpolate into the target string.
67
- #
68
- # @return [String]
69
- def self.interpolate(string, options = HASH)
70
- return string unless string.is_a?(String)
71
- return string if options.empty?
72
-
73
- format(string, options)
74
- end
75
-
76
- # Convert a Numeric to a string, particularly formatting BigDecimals to a
77
- # Float-like string representation.
78
- #
79
- # @param numeric [Numeric]
80
- #
81
- # @return [String]
82
- def self.string_from_numeric(numeric)
83
- if numeric.is_a?(BigDecimal)
84
- numeric.to_s('F')
85
- else
86
- numeric.to_s
87
- end
88
- end
89
- end
90
-
91
14
  DEFAULT = 'default'
92
15
  DELIMITING_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/.freeze
93
16
  HASH = {}.freeze
@@ -154,7 +77,7 @@ class Tater
154
77
  end
155
78
 
156
79
  Dir.glob(File.join(path, '**', '*.rb')).each do |file|
157
- @messages = Utils.deep_merge(@messages, Utils.deep_stringify_keys(eval(IO.read(file), binding, file))) # rubocop:disable Security/Eval
80
+ @messages = Utils.deep_merge(@messages, Utils.deep_stringify_keys(eval(File.read(file), binding, file))) # rubocop:disable Security/Eval
158
81
  end
159
82
  end
160
83
 
@@ -220,7 +143,6 @@ class Tater
220
143
  raise(UnLocalizableObject, "The object class #{ object.class } cannot be localized by Tater.")
221
144
  end
222
145
  end
223
- alias l localize
224
146
 
225
147
  # Lookup a key in the messages hash, using the current locale or an override.
226
148
  #
@@ -325,25 +247,39 @@ class Tater
325
247
  # The translated and interpreted string, if found, or any data at the
326
248
  # defined key.
327
249
  def translate(key, options = HASH)
328
- message =
329
- if options.key?(:locales)
330
- options[:locales].append(@locale) if @locale && !options[:locales].include?(@locale)
250
+ if options.empty?
251
+ message = lookup(key)
331
252
 
332
- options[:locales].find do |accept|
333
- found = lookup(key, locale: accept, cascade: options[:cascade])
334
-
335
- break found unless found.nil?
336
- end
253
+ if message.is_a?(Proc) # rubocop:disable Style/CaseLikeIf
254
+ message.call(key)
255
+ elsif message.is_a?(String)
256
+ message
337
257
  else
338
- lookup(key, locale: options[:locale], cascade: options[:cascade])
258
+ "Tater lookup failed: #{ locale }.#{ key }"
339
259
  end
260
+ else
261
+ message =
262
+ if options.key?(:locales)
263
+ options[:locales].append(@locale) if @locale && !options[:locales].include?(@locale)
340
264
 
341
- # Call procs that should return a string.
342
- message = message.call(key, options) if message.is_a?(Proc)
265
+ options[:locales].find do |accept|
266
+ found = lookup(key, locale: accept, cascade: options[:cascade])
343
267
 
344
- Utils.interpolate(message, options) || options[:default] || "Tater lookup failed: #{ options[:locale] || options[:locales] || locale }.#{ key }"
268
+ break found unless found.nil?
269
+ end
270
+ else
271
+ lookup(key, locale: options[:locale], cascade: options[:cascade])
272
+ end
273
+
274
+ if message.is_a?(Proc) # rubocop:disable Style/CaseLikeIf
275
+ message.call(key, options.except(:cascade, :default, :locale, :locales))
276
+ elsif message.is_a?(String)
277
+ Utils.interpolate(message, options.except(:cascade, :default, :locale, :locales))
278
+ else
279
+ options[:default] || "Tater lookup failed: #{ options[:locale] || options[:locales] || locale }.#{ key }"
280
+ end
281
+ end
345
282
  end
346
- alias t translate
347
283
 
348
284
  private
349
285
 
data/test/tater_test.rb CHANGED
@@ -61,6 +61,20 @@ describe Tater do
61
61
  assert_equal '1.0', Tater::Utils.string_from_numeric(BigDecimal('1'))
62
62
  end
63
63
  end
64
+
65
+ describe '#interpolation_string?' do
66
+ def is?(arg)
67
+ Tater::Utils.interpolation_string?(arg)
68
+ end
69
+
70
+ it 'checks whether a string contains interpolation placeholders' do
71
+ assert is?('Hey %{there}!')
72
+ assert is?('Hey %<there>s!')
73
+ refute is?('Nah, this is fine')
74
+ refute is?("<b>HTML shouldn't count")
75
+ refute is?("A single % shouldn't count")
76
+ end
77
+ end
64
78
  end
65
79
 
66
80
  describe '#available?' do
@@ -143,6 +157,10 @@ describe Tater do
143
157
  assert_nil i18n.lookup('nope')
144
158
  end
145
159
 
160
+ it 'returns arbitrary data at keys' do
161
+ assert_equal({ 'key' => 'This key is deeper' }, i18n.lookup('deep'))
162
+ end
163
+
146
164
  it 'cascades' do
147
165
  assert_equal 'Delicious', i18n.lookup('cascade.nope.tacos', cascade: true)
148
166
  assert_equal 'Whoaa', i18n.lookup('cascade.another.nope.crazy', cascade: true)
@@ -164,8 +182,8 @@ describe Tater do
164
182
  assert_equal 'This key is deeper', i18n.translate('deep.key')
165
183
  end
166
184
 
167
- it 'returns a hash for nested keys' do
168
- assert_equal({ 'key' => 'This key is deeper' }, i18n.translate('deep'))
185
+ it 'does not return a hash for nested keys' do
186
+ assert_equal 'Tater lookup failed: en.deep', i18n.translate('deep')
169
187
  end
170
188
 
171
189
  it 'interpolates additional variables' do
@@ -182,10 +200,6 @@ describe Tater do
182
200
  assert_equal 'Tater lookup failed: en.nope', i18n.translate('nope')
183
201
  end
184
202
 
185
- it 'is aliased as t' do
186
- assert_equal 'This is a title', i18n.t('title')
187
- end
188
-
189
203
  it 'cascades lookups' do
190
204
  assert_equal 'Tater lookup failed: en.cascade.another.nope.crazy', i18n.translate('cascade.another.nope.crazy', cascade: false)
191
205
  assert_equal 'Tater lookup failed: en.cascade.nope.tacos', i18n.translate('cascade.nope.tacos')
@@ -203,9 +217,12 @@ describe Tater do
203
217
  assert_equal 'Tater lookup failed: ["fr", "en"].neither', i18n.translate('neither', locales: %w[fr en])
204
218
  end
205
219
 
206
- it 'finds Ruby files as well' do
220
+ it 'finds Ruby files' do
207
221
  assert_equal 'Hey ruby!', i18n.translate('ruby')
208
- assert_equal 'Hey options!', i18n.translate('options', options: 'options')
222
+ end
223
+
224
+ it 'does not interpolate messages returned by procs' do
225
+ assert_equal 'Hey %{options}!', i18n.translate('options', options: 'options')
209
226
  end
210
227
  end
211
228
 
@@ -316,10 +333,6 @@ describe Tater do
316
333
  end
317
334
  end
318
335
 
319
- it 'is aliased l' do
320
- assert_equal '1970/1/1', i18n.l(Date.new(1970, 1, 1))
321
- end
322
-
323
336
  describe 'month, day, and AM/PM names' do
324
337
  let :i18n do
325
338
  Tater.new(path: File.expand_path('test/fixtures'), locale: 'fr')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tater
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Lecklider
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-12 00:00:00.000000000 Z
11
+ date: 2021-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -142,8 +142,9 @@ licenses:
142
142
  - MIT
143
143
  metadata:
144
144
  bug_tracker_uri: https://github.com/evanleck/tater/issues
145
+ rubygems_mfa_required: 'true'
145
146
  source_code_uri: https://github.com/evanleck/tater
146
- post_install_message:
147
+ post_install_message:
147
148
  rdoc_options: []
148
149
  require_paths:
149
150
  - lib
@@ -158,8 +159,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
159
  - !ruby/object:Gem::Version
159
160
  version: '2.0'
160
161
  requirements: []
161
- rubygems_version: 3.2.22
162
- signing_key:
162
+ rubygems_version: 3.2.32
163
+ signing_key:
163
164
  specification_version: 4
164
165
  summary: Minimal internationalization and localization library.
165
166
  test_files: