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.
- checksums.yaml +4 -4
- data/lib/tater.rb +29 -93
- data/test/tater_test.rb +25 -12
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c34d7058c3566313243c4ccb7b99d967c60bf2e00e091d1fbb66dfbd257e853f
|
4
|
+
data.tar.gz: 0a5c1d4df6a34b9953086af0459af4c72cb8d9faf674d3216e1eb9e00aa0e82f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
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
|
-
|
329
|
-
|
330
|
-
options[:locales].append(@locale) if @locale && !options[:locales].include?(@locale)
|
250
|
+
if options.empty?
|
251
|
+
message = lookup(key)
|
331
252
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
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
|
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
|
-
|
342
|
-
|
265
|
+
options[:locales].find do |accept|
|
266
|
+
found = lookup(key, locale: accept, cascade: options[:cascade])
|
343
267
|
|
344
|
-
|
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 '
|
168
|
-
assert_equal
|
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
|
220
|
+
it 'finds Ruby files' do
|
207
221
|
assert_equal 'Hey ruby!', i18n.translate('ruby')
|
208
|
-
|
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:
|
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-
|
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.
|
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:
|