i18n-complements 0.0.12 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.rdoc +1 -1
- data/lib/i18n-complements.rb +1 -15
- data/lib/i18n/complements.rb +14 -0
- data/lib/{i18n-complements → i18n/complements}/core_extension.rb +10 -10
- data/lib/i18n/complements/localize_extension.rb +55 -0
- data/lib/i18n/complements/numisma.rb +124 -0
- data/lib/{i18n-complements → i18n/complements}/numisma/currencies.yml +0 -0
- data/lib/i18n/complements/numisma/currency.rb +81 -0
- data/lib/i18n/complements/numisma/fixed_currency_rates.yml +20 -0
- data/lib/i18n/complements/version.rb +5 -0
- data/test/helper.rb +24 -2
- data/test/test_booleans.rb +4 -6
- data/test/test_currencies.rb +39 -44
- data/test/test_currency_rates.rb +20 -19
- data/test/test_extensions.rb +8 -11
- data/test/test_numbers.rb +34 -32
- data/test/test_strings.rb +7 -9
- metadata +45 -16
- data/lib/i18n-complements/localize_extension.rb +0 -53
- data/lib/i18n-complements/numisma.rb +0 -107
- data/lib/i18n-complements/numisma/currency.rb +0 -82
- data/lib/i18n-complements/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cdd3051546defefbdea07a93d272b73e439afed392c5d122cabae378e85ce74b
|
4
|
+
data.tar.gz: ce785fa0d3bd1807751dfb744eca066904823afe5280a40dea8bccda8ac19178
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe42ba93dc9828cb432e713cba3dda7134a04dd4f0574dd5dd6849f71a3f8c62f906948172859a94cb3b43637b3c21b3682e5e96fe391bf2f986db3e39682dbd
|
7
|
+
data.tar.gz: 73eb8bc1073b0c877eec418e93457369a5449bd827834bb89091d66d73edb1ffe6d11bbad8915244eb942a5964504e500e7b5dbf58685c6130b29077b7ed1c04
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=
|
1
|
+
= I18n::Complements
|
2
2
|
{<img src="https://badge.fury.io/rb/i18n-complements.png" alt="Gem Version" />}[http://badge.fury.io/rb/i18n-complements]
|
3
3
|
{<img src="https://api.travis-ci.org/ekylibre/i18n-complements.png?branch=master"/>}[https://travis-ci.org/ekylibre/i18n-complements]
|
4
4
|
{<img src="https://gemnasium.com/ekylibre/i18n-complements.png"/>}[https://gemnasium.com/ekylibre/i18n-complements]
|
data/lib/i18n-complements.rb
CHANGED
@@ -1,15 +1 @@
|
|
1
|
-
require 'i18n'
|
2
|
-
require 'i18n-complements/numisma'
|
3
|
-
require 'i18n-complements/localize_extension'
|
4
|
-
require 'i18n-complements/core_extension'
|
5
|
-
require 'i18n-complements/version'
|
6
|
-
|
7
|
-
module I18n
|
8
|
-
|
9
|
-
class InvalidCurrency < ArgumentError
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
module I18nComplements
|
15
|
-
end
|
1
|
+
require 'i18n/complements'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
module I18n
|
4
|
+
class InvalidCurrency < ArgumentError
|
5
|
+
end
|
6
|
+
|
7
|
+
module Complements
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'i18n/complements/numisma'
|
12
|
+
require 'i18n/complements/localize_extension'
|
13
|
+
require 'i18n/complements/core_extension'
|
14
|
+
require 'i18n/complements/version'
|
@@ -4,12 +4,12 @@ class ::String
|
|
4
4
|
def translate(options = {})
|
5
5
|
I18n.translate(self, options)
|
6
6
|
end
|
7
|
-
alias
|
7
|
+
alias t translate
|
8
8
|
|
9
9
|
def localize(options = {})
|
10
10
|
I18n.localize(self, options)
|
11
11
|
end
|
12
|
-
alias
|
12
|
+
alias l localize
|
13
13
|
|
14
14
|
def to_currency
|
15
15
|
I18n.currencies(self)
|
@@ -20,10 +20,10 @@ class ::Symbol
|
|
20
20
|
def translate(options = {})
|
21
21
|
I18n.translate(self, options)
|
22
22
|
end
|
23
|
-
alias
|
23
|
+
alias t translate
|
24
24
|
|
25
25
|
def to_currency
|
26
|
-
I18n.currencies(
|
26
|
+
I18n.currencies(to_s)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -31,40 +31,40 @@ class ::TrueClass
|
|
31
31
|
def localize(options = {})
|
32
32
|
I18n.localize(self, options)
|
33
33
|
end
|
34
|
-
alias
|
34
|
+
alias l localize
|
35
35
|
end
|
36
36
|
|
37
37
|
class ::FalseClass
|
38
38
|
def localize(options = {})
|
39
39
|
I18n.localize(self, options)
|
40
40
|
end
|
41
|
-
alias
|
41
|
+
alias l localize
|
42
42
|
end
|
43
43
|
|
44
44
|
class ::Numeric
|
45
45
|
def localize(options = {})
|
46
46
|
I18n.localize(self, options)
|
47
47
|
end
|
48
|
-
alias
|
48
|
+
alias l localize
|
49
49
|
end
|
50
50
|
|
51
51
|
class ::Date
|
52
52
|
def localize(options = {})
|
53
53
|
I18n.localize(self, options)
|
54
54
|
end
|
55
|
-
alias
|
55
|
+
alias l localize
|
56
56
|
end
|
57
57
|
|
58
58
|
class ::DateTime
|
59
59
|
def localize(options = {})
|
60
60
|
I18n.localize(self, options)
|
61
61
|
end
|
62
|
-
alias
|
62
|
+
alias l localize
|
63
63
|
end
|
64
64
|
|
65
65
|
class ::Time
|
66
66
|
def localize(options = {})
|
67
67
|
I18n.localize(self, options)
|
68
68
|
end
|
69
|
-
alias
|
69
|
+
alias l localize
|
70
70
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module I18n
|
2
|
+
module Backend
|
3
|
+
class Simple
|
4
|
+
def localize_with_complements(locale, object, format = nil, options = {})
|
5
|
+
if object.respond_to?(:strftime)
|
6
|
+
format ||= :default
|
7
|
+
return localize_without_complements(locale, object, format, options)
|
8
|
+
elsif object.respond_to?(:abs)
|
9
|
+
if currency = options[:currency]
|
10
|
+
raise I18n::InvalidCurrency, "Currency #{currency} does not exist." unless I18n::Complements::Numisma[currency.to_s]
|
11
|
+
return I18n::Complements::Numisma[currency.to_s].localize(object, locale: locale)
|
12
|
+
else
|
13
|
+
formatter = I18n.translate('number.format'.to_sym, locale: locale, default: {})
|
14
|
+
if formatter.is_a?(Proc)
|
15
|
+
return formatter[object]
|
16
|
+
elsif formatter.is_a?(Hash)
|
17
|
+
formatter = { format: '%n', separator: '.', delimiter: '', precision: 3 }.merge(formatter).merge(options)
|
18
|
+
format = formatter[:format]
|
19
|
+
negative_format = formatter[:negative_format] || '-' + format
|
20
|
+
|
21
|
+
if object.to_f < 0
|
22
|
+
format = negative_format
|
23
|
+
object = object.abs
|
24
|
+
end
|
25
|
+
|
26
|
+
formatter[:delimiter] = "\u{00A0}" if formatter[:delimiter] == ' '
|
27
|
+
|
28
|
+
value = object.to_s.split(/\./)
|
29
|
+
integrals = value[0].to_s
|
30
|
+
decimals = value[1].to_s
|
31
|
+
value = integrals.gsub(/^0+[1-9]+/, '').gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{formatter[:delimiter]}")
|
32
|
+
decimals = '0' if decimals.to_s.match(/^\s*$/) && object.is_a?(Float)
|
33
|
+
unless decimals.to_s =~ /^\s*$/
|
34
|
+
after = decimals.gsub(/0+$/, '').ljust(formatter[:precision], '0').scan(/.{1,3}/).join('')
|
35
|
+
unless after =~ /\A[[:space:]]*\z/
|
36
|
+
value << formatter[:separator] + after
|
37
|
+
end
|
38
|
+
end
|
39
|
+
return format.gsub(/%n/, value).gsub(/%s/, "\u{00A0}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
elsif object.is_a?(TrueClass) || object.is_a?(FalseClass)
|
43
|
+
return I18n.translate("boolean.human.#{object}_class", locale: locale)
|
44
|
+
elsif object.is_a?(String)
|
45
|
+
return object
|
46
|
+
else
|
47
|
+
raise ArgumentError, "Object must be a Numeric, TrueClass, FalseClass, String, Date, DateTime or Time object. #{object.class.name}:#{object.inspect} given."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
alias localize_without_complements localize
|
52
|
+
alias localize localize_with_complements
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# This module aimed to structure and controls currencies through the application
|
2
|
+
# It represents the international monetary system with all its currencies like specified in ISO 4217
|
3
|
+
# Numisma comes from latin: It designs here the "science of money"
|
4
|
+
require 'net/http'
|
5
|
+
require 'yaml'
|
6
|
+
require 'i18n/complements/numisma/currency'
|
7
|
+
|
8
|
+
module I18n
|
9
|
+
module Complements
|
10
|
+
module Numisma
|
11
|
+
class << self
|
12
|
+
def currencies
|
13
|
+
@@currencies
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the path to currencies file
|
17
|
+
def currencies_file
|
18
|
+
# Rails.root.join("config", "currencies.yml")
|
19
|
+
File.join(File.dirname(__FILE__), 'numisma', 'currencies.yml')
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a hash with active currencies only
|
23
|
+
def active_currencies
|
24
|
+
x = {}
|
25
|
+
@@currencies.each do |code, currency|
|
26
|
+
x[code] = currency if currency.active
|
27
|
+
end
|
28
|
+
x
|
29
|
+
end
|
30
|
+
|
31
|
+
# Shorcut to get currency
|
32
|
+
def [](currency_code)
|
33
|
+
@@currencies[currency_code]
|
34
|
+
end
|
35
|
+
|
36
|
+
def fixed_currency_rate(from, to)
|
37
|
+
rates = @@fixed_currency_rates[from]
|
38
|
+
return nil unless rates
|
39
|
+
rates[to]
|
40
|
+
end
|
41
|
+
|
42
|
+
def currency_rate(from, to)
|
43
|
+
if Numisma[from].nil?
|
44
|
+
raise InvalidCurrency, ":from currency is unknown (#{from.class}:#{from.inspect})"
|
45
|
+
end
|
46
|
+
if Numisma[to].nil?
|
47
|
+
raise InvalidCurrency, ":to currency is unknown (#{to.class}:#{to.inspect})"
|
48
|
+
end
|
49
|
+
rate = fixed_currency_rate(from, to)
|
50
|
+
return rate if rate
|
51
|
+
begin
|
52
|
+
uri = URI('http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate')
|
53
|
+
response = Net::HTTP.post_form(uri, 'FromCurrency' => from, 'ToCurrency' => to)
|
54
|
+
doc = ::LibXML::XML::Parser.string(response.body).parse
|
55
|
+
rate = doc.root.content.to_f
|
56
|
+
rescue
|
57
|
+
uri = URI("http://download.finance.yahoo.com/d/quotes.csv?s=#{from}#{to}=X&f=l1")
|
58
|
+
response = Net::HTTP.get(uri)
|
59
|
+
rate = response.strip.to_f
|
60
|
+
end
|
61
|
+
rate
|
62
|
+
end
|
63
|
+
|
64
|
+
# Load currencies
|
65
|
+
def load_currencies
|
66
|
+
@@currencies = {}
|
67
|
+
yaml = YAML.load_file(currencies_file)
|
68
|
+
yaml.each do |code, attributes|
|
69
|
+
currency = Currency.new(code, attributes.inject({}) { |h, p| h[p[0].to_sym] = p[1]; h })
|
70
|
+
@@currencies[currency.code] = currency
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Load fixed currency rates with reverse rates too.
|
75
|
+
def load_fixed_currency_rates
|
76
|
+
@@fixed_currency_rates = {}
|
77
|
+
yaml = YAML.load_file(File.join(File.dirname(__FILE__), 'numisma', 'fixed_currency_rates.yml'))
|
78
|
+
yaml.each do |from, rates|
|
79
|
+
@@fixed_currency_rates[from] ||= {}
|
80
|
+
rates.each do |to, rate|
|
81
|
+
@@fixed_currency_rates[from][to] = rate
|
82
|
+
@@fixed_currency_rates[to] ||= {}
|
83
|
+
@@fixed_currency_rates[to][from] = 1 / rate
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Finally load all currencies
|
90
|
+
load_currencies
|
91
|
+
load_fixed_currency_rates
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def currencies(currency_code)
|
97
|
+
I18n::Complements::Numisma.currencies[currency_code.to_s]
|
98
|
+
end
|
99
|
+
|
100
|
+
def active_currencies
|
101
|
+
I18n::Complements::Numisma.active_currencies
|
102
|
+
end
|
103
|
+
|
104
|
+
def available_currencies
|
105
|
+
I18n::Complements::Numisma.currencies
|
106
|
+
end
|
107
|
+
|
108
|
+
def currency_label(currency_code)
|
109
|
+
if currency = I18n::Complements::Numisma.currencies[currency_code.to_s]
|
110
|
+
currency.label
|
111
|
+
else
|
112
|
+
return "Unknown currency: #{currency_code}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def currency_rate(from, to)
|
117
|
+
I18n::Complements::Numisma.currency_rate(from, to)
|
118
|
+
end
|
119
|
+
|
120
|
+
def currencies_file
|
121
|
+
I18n::Complements::Numisma.currencies_file
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
File without changes
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module I18n
|
2
|
+
module Complements
|
3
|
+
module Numisma
|
4
|
+
class Currency
|
5
|
+
attr_reader :code, :active, :cash, :countries, :number, :precision, :unit
|
6
|
+
|
7
|
+
def initialize(code, options = {})
|
8
|
+
@code = code.strip # .upcase
|
9
|
+
@active = (options[:active] ? true : false)
|
10
|
+
@cash = options[:cash].to_a.collect(&:to_f).sort
|
11
|
+
@countries = options[:countries].to_a.collect(&:to_s).sort.collect(&:to_sym)
|
12
|
+
@number = options[:number].to_i
|
13
|
+
@precision = options[:precision].to_i
|
14
|
+
@unit = (options[:unit].nil? ? nil : options[:unit].to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
::I18n.translate("currencies.#{code}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def label
|
22
|
+
::I18n.translate('labels.currency_with_code', code: code, name: name, default: '%{name} (%{code})')
|
23
|
+
end
|
24
|
+
|
25
|
+
def round(value, _options = {})
|
26
|
+
precision = self.precision
|
27
|
+
if RUBY_VERSION =~ /^1\.8/
|
28
|
+
magnitude = 10**precision
|
29
|
+
return (value * magnitude).to_i.to_f * magnitude
|
30
|
+
else
|
31
|
+
return value.round(precision)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def ==(other_currency)
|
36
|
+
code == other_currency.code
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_currency
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
# Produces a amount of the currency with the locale parameters
|
44
|
+
# TODO: Find a better way to specify number formats which are more complex that the default Rails use
|
45
|
+
def localize(amount, options = {})
|
46
|
+
return unless amount
|
47
|
+
|
48
|
+
# options.symbolize_keys!
|
49
|
+
|
50
|
+
defaults = I18n.translate('number.format'.to_sym, locale: options[:locale], default: {})
|
51
|
+
defaultt = I18n.translate('number.currency.format'.to_sym, locale: options[:locale], default: {})
|
52
|
+
defaultt[:negative_format] ||= ('-' + defaultt[:format]) if defaultt[:format]
|
53
|
+
formatcy = I18n.translate("number.currency.formats.#{code}".to_sym, locale: options[:locale], default: {})
|
54
|
+
formatcy[:negative_format] ||= '-' + formatcy[:format] if formatcy[:format]
|
55
|
+
|
56
|
+
formatter = {}
|
57
|
+
formatter[:separator] = formatcy[:separator] || defaultt[:separator] || defaults[:separator] || ','
|
58
|
+
formatter[:delimiter] = formatcy[:delimiter] || defaultt[:delimiter] || defaults[:delimiter] || ''
|
59
|
+
formatter[:precision] = formatcy[:precision] || precision || defaultt[:precision] || 3
|
60
|
+
format = formatcy[:format] || defaultt[:format] || '%n-%u' # defaults[:format] ||
|
61
|
+
negative_format = formatcy[:negative_format] || defaultt[:negative_format] || defaults[:negative_format] || '-' + format
|
62
|
+
unit = formatcy[:unit] || self.unit || code
|
63
|
+
|
64
|
+
if amount.to_f < 0
|
65
|
+
format = negative_format # options.delete(:negative_format)
|
66
|
+
amount = amount.respond_to?('abs') ? amount.abs : amount.sub(/^-/, '')
|
67
|
+
end
|
68
|
+
|
69
|
+
value = amount.to_s
|
70
|
+
integers, decimals = value.split(/\./)
|
71
|
+
value = integers.gsub(/^0+[1-9]+/, '').gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{formatter[:delimiter]}")
|
72
|
+
unless decimals.to_s =~ /^\s*$/
|
73
|
+
value << formatter[:separator]
|
74
|
+
value << decimals.gsub(/0+$/, '').ljust(formatter[:precision], '0').scan(/.{1,3}/).join(formatter[:delimiter])
|
75
|
+
end
|
76
|
+
format.gsub(/%n/, value).gsub(/%u/, unit).gsub(/%s/, "\u{00A0}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
EUR:
|
2
|
+
EEK: 15.6466
|
3
|
+
SKK: 30.126
|
4
|
+
GRD: 340.75
|
5
|
+
PTE: 200.482
|
6
|
+
NLG: 2.20371
|
7
|
+
BEF: 40.3399
|
8
|
+
FRF: 6.55957
|
9
|
+
LUF: 40.3399
|
10
|
+
LVL: 0.702804
|
11
|
+
ITL: 1936.27
|
12
|
+
MTL: 0.4293
|
13
|
+
LTL: 3.4528
|
14
|
+
CYP: 0.585274
|
15
|
+
IEP: 0.787564
|
16
|
+
DEM: 1.95583
|
17
|
+
FIM: 5.94573
|
18
|
+
ESP: 166.386
|
19
|
+
ATS: 13.7603
|
20
|
+
SIT: 239.64
|
data/test/helper.rb
CHANGED
@@ -2,13 +2,35 @@ require 'coveralls'
|
|
2
2
|
Coveralls.wear!
|
3
3
|
|
4
4
|
require 'bundler/setup'
|
5
|
-
require '
|
5
|
+
require 'minitest/autorun'
|
6
6
|
|
7
7
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
8
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
9
|
|
10
10
|
require 'i18n-complements'
|
11
11
|
|
12
|
-
|
12
|
+
Dir[File.join(File.dirname(__FILE__), 'locales', '*.yml')].each do |file|
|
13
13
|
I18n.backend.load_translations(file)
|
14
14
|
end
|
15
|
+
|
16
|
+
module I18n
|
17
|
+
module Complements
|
18
|
+
class TestCase < Minitest::Test
|
19
|
+
def setup
|
20
|
+
I18n.locale = ENV['LOCALE'] || :eng
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_nothing_raised(*_args)
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
|
27
|
+
def assert_raise(exception)
|
28
|
+
yield
|
29
|
+
rescue Exception => e
|
30
|
+
assert_equal exception, e.class
|
31
|
+
else
|
32
|
+
refute
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/test/test_booleans.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestBooleans <
|
5
|
-
|
4
|
+
class TestBooleans < I18n::Complements::TestCase
|
6
5
|
def test_localization
|
7
6
|
assert_nothing_raised do
|
8
7
|
I18n.localize(true)
|
@@ -20,15 +19,14 @@ class TestBooleans < Test::Unit::TestCase
|
|
20
19
|
|
21
20
|
assert_nothing_raised do
|
22
21
|
false.localize
|
23
|
-
end
|
22
|
+
end
|
24
23
|
|
25
24
|
assert_nothing_raised do
|
26
25
|
true.l
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
assert_nothing_raised do
|
30
29
|
false.l
|
31
|
-
end
|
30
|
+
end
|
32
31
|
end
|
33
|
-
|
34
32
|
end
|
data/test/test_currencies.rb
CHANGED
@@ -1,67 +1,65 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestCurrencies <
|
5
|
-
|
4
|
+
class TestCurrencies < I18n::Complements::TestCase
|
6
5
|
def test_localization_with_currency
|
7
6
|
assert_nothing_raised do
|
8
|
-
::I18n.localize(14.5, :
|
7
|
+
::I18n.localize(14.5, currency: :JPY)
|
9
8
|
end
|
10
9
|
|
11
10
|
assert_nothing_raised do
|
12
|
-
::I18n.localize(14.5, :
|
11
|
+
::I18n.localize(14.5, currency: 'JPY')
|
13
12
|
end
|
14
|
-
|
13
|
+
|
15
14
|
assert_raise(I18n::InvalidCurrency) do
|
16
|
-
::I18n.localize(14.5, :
|
15
|
+
::I18n.localize(14.5, currency: 'jPY')
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
def test_localization_with_currency_with_core_extensions
|
21
20
|
assert_nothing_raised do
|
22
|
-
14.5.localize(:
|
21
|
+
14.5.localize(currency: :JPY)
|
23
22
|
end
|
24
23
|
|
25
24
|
assert_nothing_raised do
|
26
|
-
14.5.l(:
|
25
|
+
14.5.l(currency: :JPY)
|
27
26
|
end
|
28
27
|
|
29
28
|
assert_nothing_raised do
|
30
|
-
|
29
|
+
13_546.localize(currency: :JPY)
|
31
30
|
end
|
32
|
-
|
31
|
+
|
33
32
|
assert_nothing_raised do
|
34
|
-
|
33
|
+
13_546.l(currency: :JPY)
|
35
34
|
end
|
36
|
-
|
35
|
+
|
37
36
|
assert_raise(I18n::InvalidCurrency) do
|
38
|
-
14.5.l(:
|
39
|
-
end
|
37
|
+
14.5.l(currency: 'jPY')
|
38
|
+
end
|
40
39
|
|
41
40
|
assert_raise(I18n::InvalidCurrency) do
|
42
|
-
14.5.l(:
|
43
|
-
end
|
41
|
+
14.5.l(currency: 'JPYXX')
|
42
|
+
end
|
44
43
|
end
|
45
|
-
|
44
|
+
|
46
45
|
def test_number_formatting_with_currency
|
47
|
-
number =
|
48
|
-
assert_equal
|
49
|
-
assert_equal "413\u{00A0}500\u{00A0}¥", ::I18n.localize(number, :
|
50
|
-
assert_equal
|
51
|
-
assert_equal
|
52
|
-
assert_equal "0,325\u{00A0}1\u{00A0}F", ::I18n.localize(0.3251, :
|
53
|
-
assert_equal
|
46
|
+
number = 413_500
|
47
|
+
assert_equal '¥413,500', ::I18n.localize(number, locale: :eng, currency: 'JPY')
|
48
|
+
assert_equal "413\u{00A0}500\u{00A0}¥", ::I18n.localize(number, locale: :fra, currency: 'JPY')
|
49
|
+
assert_equal '413,500円', ::I18n.localize(number, locale: :jpn, currency: 'JPY')
|
50
|
+
assert_equal '€0.325,1', ::I18n.localize(0.3251, locale: :eng, currency: 'EUR')
|
51
|
+
assert_equal "0,325\u{00A0}1\u{00A0}F", ::I18n.localize(0.3251, locale: :fra, currency: 'FRF')
|
52
|
+
assert_equal '€123,852.325,1', ::I18n.localize(123_852.3251, locale: :eng, currency: 'EUR')
|
54
53
|
end
|
55
54
|
|
56
55
|
def test_number_formatting_with_currency_with_core_extensions
|
57
|
-
|
58
|
-
|
59
|
-
assert_equal(money[0].l(:locale
|
56
|
+
[:eng, :fra, :jpn].each do |locale|
|
57
|
+
[[413_500, 'JPY'], [1425.23, 'USD'], [0.96, 'EUR']].each do |money|
|
58
|
+
assert_equal(money[0].l(locale: locale, currency: money[1]), ::I18n.localize(money[0], locale: locale, currency: money[1]))
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
64
|
-
|
65
63
|
def test_listing_of_currencies
|
66
64
|
assert_nothing_raised do
|
67
65
|
::I18n.active_currencies
|
@@ -71,32 +69,32 @@ class TestCurrencies < Test::Unit::TestCase
|
|
71
69
|
::I18n.available_currencies
|
72
70
|
end
|
73
71
|
|
74
|
-
assert ::I18n.active_currencies.size <= ::I18n.available_currencies.size,
|
72
|
+
assert ::I18n.active_currencies.size <= ::I18n.available_currencies.size, 'Available currencies cannot be less numerous than active currencies'
|
75
73
|
end
|
76
74
|
|
77
75
|
def test_currency_properties
|
78
76
|
assert !::I18n.currencies(:JPY).nil?
|
79
|
-
assert !::I18n.currencies(
|
80
|
-
assert ::I18n.currencies(
|
77
|
+
assert !::I18n.currencies('JPY').nil?
|
78
|
+
assert ::I18n.currencies('JPy').nil?
|
81
79
|
|
82
|
-
assert !::I18n.currencies(
|
83
|
-
assert !::I18n.currencies(
|
80
|
+
assert !::I18n.currencies('USD').nil?
|
81
|
+
assert !::I18n.currencies('EUR').nil?
|
84
82
|
|
85
|
-
assert ::I18n.currencies(
|
83
|
+
assert ::I18n.currencies('JPYXX').nil?
|
86
84
|
|
87
85
|
assert_nothing_raised do
|
88
|
-
::I18n.currency_label(
|
86
|
+
::I18n.currency_label('JPY')
|
89
87
|
end
|
90
|
-
assert !::I18n.currency_label(
|
88
|
+
assert !::I18n.currency_label('JPY').match(/Unknown/)
|
91
89
|
end
|
92
|
-
|
90
|
+
|
93
91
|
def test_currency_properties_with_core_extensions
|
94
92
|
assert_nothing_raised do
|
95
93
|
:JPY.to_currency.name
|
96
94
|
end
|
97
|
-
|
95
|
+
|
98
96
|
assert_nothing_raised do
|
99
|
-
|
97
|
+
'USD'.to_currency.name
|
100
98
|
end
|
101
99
|
|
102
100
|
assert_nothing_raised do
|
@@ -106,15 +104,12 @@ class TestCurrencies < Test::Unit::TestCase
|
|
106
104
|
assert_nothing_raised do
|
107
105
|
:JPY.to_currency.to_currency.to_currency.name
|
108
106
|
end
|
109
|
-
|
107
|
+
|
110
108
|
assert_equal :JPY.to_currency, :JPY.to_currency.to_currency
|
111
109
|
|
112
110
|
currency = :JPY.to_currency
|
113
|
-
|
111
|
+
|
114
112
|
assert_equal currency, currency.to_currency
|
115
113
|
assert_equal currency.to_currency, currency.to_currency.to_currency
|
116
114
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
115
|
end
|
data/test/test_currency_rates.rb
CHANGED
@@ -1,31 +1,32 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestCurrencies <
|
5
|
-
|
4
|
+
class TestCurrencies < I18n::Complements::TestCase
|
6
5
|
def test_conversion_rate
|
6
|
+
rate = I18n::Complements::Numisma.currency_rate('EUR', 'FRF')
|
7
|
+
assert !rate.zero?, 'Rate should not be zero'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
assert_raise ArgumentError do
|
13
|
-
I18nComplements::Numisma.currency_rate("EUR", :JPY)
|
14
|
-
end
|
15
|
-
|
16
|
-
assert_raise ArgumentError do
|
17
|
-
I18nComplements::Numisma.currency_rate(:EUR, :JPY)
|
9
|
+
assert rate == 6.55957
|
10
|
+
|
11
|
+
assert_raise I18n::InvalidCurrency do
|
12
|
+
I18n::Complements::Numisma.currency_rate(:EUR, 'JPY')
|
18
13
|
end
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
assert 0.01 >= 1 - (r1 * r2).round(2)
|
23
|
-
|
24
|
-
assert_nothing_raised do
|
25
|
-
I18nComplements::Numisma.currency_rate("EUR", "JPY")
|
15
|
+
assert_raise I18n::InvalidCurrency do
|
16
|
+
I18n::Complements::Numisma.currency_rate('EUR', :JPY)
|
26
17
|
end
|
27
18
|
|
28
|
-
|
19
|
+
assert_raise I18n::InvalidCurrency do
|
20
|
+
I18n::Complements::Numisma.currency_rate(:EUR, :JPY)
|
21
|
+
end
|
29
22
|
|
23
|
+
r1 = I18n::Complements::Numisma.currency_rate('EUR', 'JPY')
|
24
|
+
r2 = I18n::Complements::Numisma.currency_rate('JPY', 'EUR')
|
25
|
+
rounded_one = (r1 * r2).round(2)
|
26
|
+
assert rounded_one >= 0.99, "EUR -> JPY: #{r1}, JPY -> EUR: #{r2}, #{r1 * r2}, #{rounded_one}"
|
30
27
|
|
28
|
+
rate = I18n::Complements::Numisma.currency_rate('EUR', 'JPY')
|
29
|
+
assert !rate.nil?, 'Rate cannot be nil'
|
30
|
+
assert rate != 0, 'Rate cannot be null'
|
31
|
+
end
|
31
32
|
end
|
data/test/test_extensions.rb
CHANGED
@@ -1,29 +1,27 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestExtensions <
|
5
|
-
|
4
|
+
class TestExtensions < I18n::Complements::TestCase
|
6
5
|
def setup
|
7
6
|
I18n.locale = :eng
|
8
7
|
end
|
9
8
|
|
10
9
|
def test_string_translation
|
11
|
-
assert_equal
|
12
|
-
assert_equal I18n.translate(
|
13
|
-
assert_equal I18n.translate(
|
10
|
+
assert_equal 'My example is so short', I18n.translate('my_example')
|
11
|
+
assert_equal I18n.translate('my_example'), 'my_example'.translate
|
12
|
+
assert_equal I18n.translate('my_example'), 'my_example'.t
|
14
13
|
|
15
|
-
assert_equal
|
16
|
-
assert_equal I18n.translate(
|
17
|
-
assert_equal I18n.translate(
|
14
|
+
assert_equal 'My example is short', I18n.translate('my.example')
|
15
|
+
assert_equal I18n.translate('my.example'), 'my.example'.translate
|
16
|
+
assert_equal I18n.translate('my.example'), 'my.example'.t
|
18
17
|
end
|
19
18
|
|
20
19
|
def test_symbol_translation
|
21
|
-
assert_equal
|
20
|
+
assert_equal 'My example is so short', I18n.translate(:my_example)
|
22
21
|
assert_equal I18n.translate(:my_example), :my_example.translate
|
23
22
|
assert_equal I18n.translate(:my_example), :my_example.t
|
24
23
|
end
|
25
24
|
|
26
|
-
|
27
25
|
def test_date_localization
|
28
26
|
date = Date.civil(1999, 12, 31)
|
29
27
|
|
@@ -71,5 +69,4 @@ class TestExtensions < Test::Unit::TestCase
|
|
71
69
|
|
72
70
|
assert_equal I18n.localize(time), time.l
|
73
71
|
end
|
74
|
-
|
75
72
|
end
|
data/test/test_numbers.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestNumbers <
|
5
|
-
|
4
|
+
class TestNumbers < I18n::Complements::TestCase
|
6
5
|
def test_localization
|
7
6
|
assert_nothing_raised do
|
8
7
|
I18n.localize(14.5)
|
9
8
|
end
|
10
9
|
|
11
10
|
assert_nothing_raised do
|
12
|
-
I18n.localize(
|
11
|
+
I18n.localize(413_500)
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
@@ -19,72 +18,75 @@ class TestNumbers < Test::Unit::TestCase
|
|
19
18
|
end
|
20
19
|
|
21
20
|
assert_nothing_raised do
|
22
|
-
|
23
|
-
end
|
21
|
+
413_500.localize
|
22
|
+
end
|
24
23
|
|
25
24
|
assert_nothing_raised do
|
26
25
|
14.5.l
|
27
26
|
end
|
28
27
|
|
29
28
|
assert_nothing_raised do
|
30
|
-
|
31
|
-
end
|
29
|
+
413_500.l
|
30
|
+
end
|
32
31
|
end
|
33
|
-
|
32
|
+
|
34
33
|
def test_number_formatting
|
35
34
|
# Integer
|
36
35
|
number = 3
|
37
|
-
assert_equal
|
38
|
-
assert_equal
|
36
|
+
assert_equal '3', I18n.localize(number, locale: :eng)
|
37
|
+
assert_equal '3', I18n.localize(number, locale: :fra)
|
39
38
|
|
40
39
|
# Integer > 1000
|
41
|
-
number =
|
42
|
-
assert_equal
|
43
|
-
assert_equal "21\u{00A0}145", I18n.localize(number, :
|
40
|
+
number = 21_145
|
41
|
+
assert_equal '21,145', I18n.localize(number, locale: :eng)
|
42
|
+
assert_equal "21\u{00A0}145", I18n.localize(number, locale: :fra)
|
44
43
|
|
45
44
|
# Float without integers with decimals
|
46
45
|
number = 0.5
|
47
|
-
assert_equal
|
48
|
-
assert_equal
|
46
|
+
assert_equal '0.500', I18n.localize(number, locale: :eng)
|
47
|
+
assert_equal '0,500', I18n.localize(number, locale: :fra)
|
49
48
|
|
50
49
|
# Float without decimals
|
51
50
|
number = 3.0
|
52
|
-
assert_equal
|
53
|
-
assert_equal
|
51
|
+
assert_equal '3.000', I18n.localize(number, locale: :eng)
|
52
|
+
assert_equal '3,000', I18n.localize(number, locale: :fra)
|
53
|
+
|
54
|
+
# Float without decimals and no precision
|
55
|
+
number = 5.0
|
56
|
+
assert_equal '5', I18n.localize(number, locale: :eng, precision: 0)
|
57
|
+
assert_equal '5', I18n.localize(number, locale: :fra, precision: 0)
|
54
58
|
|
55
59
|
# Float
|
56
60
|
number = 14.53
|
57
|
-
assert_equal
|
58
|
-
assert_equal
|
61
|
+
assert_equal '14.530', I18n.localize(number, locale: :eng)
|
62
|
+
assert_equal '14,530', I18n.localize(number, locale: :fra)
|
59
63
|
|
60
64
|
# Float > 1000
|
61
65
|
number = 2114.5
|
62
|
-
assert_equal
|
63
|
-
assert_equal "2\u{00A0}114,500", I18n.localize(number, :
|
66
|
+
assert_equal '2,114.500', I18n.localize(number, locale: :eng)
|
67
|
+
assert_equal "2\u{00A0}114,500", I18n.localize(number, locale: :fra)
|
64
68
|
|
65
69
|
# Float without integers with decimals < 0.001
|
66
70
|
number = 0.41421356
|
67
|
-
assert_equal
|
68
|
-
assert_equal "0,414\u{00A0}213\u{00A0}56", I18n.localize(number, :
|
71
|
+
assert_equal '0.414,213,56', I18n.localize(number, locale: :eng)
|
72
|
+
assert_equal "0,414\u{00A0}213\u{00A0}56", I18n.localize(number, locale: :fra)
|
69
73
|
|
70
74
|
# Float without integers with decimals < 0.001
|
71
75
|
number = 3.1415926
|
72
|
-
assert_equal
|
73
|
-
assert_equal "3,141\u{00A0}592\u{00A0}6", I18n.localize(number, :
|
76
|
+
assert_equal '3.141,592,6', I18n.localize(number, locale: :eng)
|
77
|
+
assert_equal "3,141\u{00A0}592\u{00A0}6", I18n.localize(number, locale: :fra)
|
74
78
|
|
75
79
|
# Float without integers with decimals < 0.001
|
76
|
-
number =
|
77
|
-
assert_equal
|
78
|
-
assert_equal "62\u{00A0}951\u{00A0}413,141\u{00A0}592\u{00A0}6", I18n.localize(number, :
|
80
|
+
number = 62_951_413.1415926
|
81
|
+
assert_equal '62,951,413.141,592,6', I18n.localize(number, locale: :eng)
|
82
|
+
assert_equal "62\u{00A0}951\u{00A0}413,141\u{00A0}592\u{00A0}6", I18n.localize(number, locale: :fra)
|
79
83
|
end
|
80
84
|
|
81
85
|
def test_number_formatting_with_core_extensions
|
82
86
|
for locale in [:eng, :fra, :jpn]
|
83
|
-
for number in [3,
|
84
|
-
assert_equal(number.l(:
|
87
|
+
for number in [3, 21_145, 0.5, 3.0, 14.53, 2144.5, 0.41421356, 3.1415926, 62_951_413.1415926]
|
88
|
+
assert_equal(number.l(locale: locale), I18n.localize(number, locale: locale))
|
85
89
|
end
|
86
90
|
end
|
87
|
-
|
88
91
|
end
|
89
|
-
|
90
92
|
end
|
data/test/test_strings.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class TestStrings <
|
5
|
-
|
4
|
+
class TestStrings < I18n::Complements::TestCase
|
6
5
|
def test_localization
|
7
6
|
assert_nothing_raised do
|
8
|
-
I18n.localize(
|
7
|
+
I18n.localize('This is a test sentence')
|
9
8
|
end
|
10
9
|
|
11
10
|
assert_nothing_raised do
|
@@ -13,26 +12,25 @@ class TestStrings < Test::Unit::TestCase
|
|
13
12
|
end
|
14
13
|
|
15
14
|
assert_nothing_raised do
|
16
|
-
I18n.localize(
|
15
|
+
I18n.localize('')
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
def test_localization_with_core_extensions
|
21
20
|
assert_nothing_raised do
|
22
|
-
|
21
|
+
'This is a test sentence'.localize
|
23
22
|
end
|
24
23
|
|
25
24
|
assert_nothing_raised do
|
26
25
|
"C'est une phrase d'exemple axée sur les caractères spéciaux".localize
|
27
|
-
end
|
26
|
+
end
|
28
27
|
|
29
28
|
assert_nothing_raised do
|
30
|
-
|
29
|
+
'This is a test sentence'.l
|
31
30
|
end
|
32
31
|
|
33
32
|
assert_nothing_raised do
|
34
33
|
"C'est une phrase d'exemple axée sur les caractères spéciaux".l
|
35
|
-
end
|
34
|
+
end
|
36
35
|
end
|
37
|
-
|
38
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-complements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brice Texier
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -28,16 +28,44 @@ dependencies:
|
|
28
28
|
name: coveralls
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.6.3
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: term-ansicolor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,7 +80,7 @@ dependencies:
|
|
52
80
|
- - ">"
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '10'
|
55
|
-
description:
|
83
|
+
description:
|
56
84
|
email: burisu@oneiros.fr
|
57
85
|
executables: []
|
58
86
|
extensions: []
|
@@ -63,12 +91,14 @@ files:
|
|
63
91
|
- LICENSE
|
64
92
|
- README.rdoc
|
65
93
|
- lib/i18n-complements.rb
|
66
|
-
- lib/i18n
|
67
|
-
- lib/i18n
|
68
|
-
- lib/i18n
|
69
|
-
- lib/i18n
|
70
|
-
- lib/i18n
|
71
|
-
- lib/i18n
|
94
|
+
- lib/i18n/complements.rb
|
95
|
+
- lib/i18n/complements/core_extension.rb
|
96
|
+
- lib/i18n/complements/localize_extension.rb
|
97
|
+
- lib/i18n/complements/numisma.rb
|
98
|
+
- lib/i18n/complements/numisma/currencies.yml
|
99
|
+
- lib/i18n/complements/numisma/currency.rb
|
100
|
+
- lib/i18n/complements/numisma/fixed_currency_rates.yml
|
101
|
+
- lib/i18n/complements/version.rb
|
72
102
|
- test/helper.rb
|
73
103
|
- test/locales/eng.yml
|
74
104
|
- test/locales/fra.yml
|
@@ -83,7 +113,7 @@ homepage: http://github.com/burisu/i18n-complements
|
|
83
113
|
licenses:
|
84
114
|
- MIT
|
85
115
|
metadata: {}
|
86
|
-
post_install_message:
|
116
|
+
post_install_message:
|
87
117
|
rdoc_options: []
|
88
118
|
require_paths:
|
89
119
|
- lib
|
@@ -98,9 +128,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
128
|
- !ruby/object:Gem::Version
|
99
129
|
version: '0'
|
100
130
|
requirements: []
|
101
|
-
|
102
|
-
|
103
|
-
signing_key:
|
131
|
+
rubygems_version: 3.0.3
|
132
|
+
signing_key:
|
104
133
|
specification_version: 4
|
105
134
|
summary: I18n missing functionnalities
|
106
135
|
test_files:
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module I18n
|
2
|
-
module Backend
|
3
|
-
|
4
|
-
class Simple
|
5
|
-
|
6
|
-
def localize_with_complements(locale, object, format = :default, options = {})
|
7
|
-
|
8
|
-
if object.respond_to?(:strftime)
|
9
|
-
return localize_without_complements(locale, object, format, options)
|
10
|
-
elsif object.respond_to?(:abs)
|
11
|
-
if currency = options[:currency]
|
12
|
-
raise I18n::InvalidCurrency.new("Currency #{currency.to_s} does not exist.") unless I18nComplements::Numisma[currency.to_s]
|
13
|
-
return I18nComplements::Numisma[currency.to_s].localize(object, :locale => locale)
|
14
|
-
else
|
15
|
-
formatter = I18n.translate('number.format'.to_sym, :locale => locale, :default => {})
|
16
|
-
if formatter.is_a?(Proc)
|
17
|
-
return formatter[object]
|
18
|
-
elsif formatter.is_a?(Hash)
|
19
|
-
formatter = {:format => "%n", :separator => '.', :delimiter => '', :precision => 3}.merge(formatter).merge(options)
|
20
|
-
format = formatter[:format]
|
21
|
-
negative_format = formatter[:negative_format] || "-" + format
|
22
|
-
|
23
|
-
if object.to_f < 0
|
24
|
-
format = negative_format
|
25
|
-
object = object.abs
|
26
|
-
end
|
27
|
-
|
28
|
-
value = object.to_s.split(/\./)
|
29
|
-
integrals, decimals = value[0].to_s, value[1].to_s
|
30
|
-
value = integrals.gsub(/^0+[1-9]+/, '').gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{formatter[:delimiter]}")
|
31
|
-
decimals = "0" if decimals.to_s.match(/^\s*$/) and object.is_a?(Float)
|
32
|
-
unless decimals.to_s.match(/^\s*$/)
|
33
|
-
value << formatter[:separator]
|
34
|
-
value << decimals.gsub(/0+$/, '').ljust(formatter[:precision], '0').scan(/.{1,3}/).join(formatter[:delimiter])
|
35
|
-
end
|
36
|
-
return format.gsub(/%n/, value).gsub(/%s/, "\u{00A0}")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
elsif object.is_a?(TrueClass) or object.is_a?(FalseClass)
|
40
|
-
return I18n.translate("boolean.formats.#{format}.#{object.to_s}")
|
41
|
-
elsif object.is_a?(String)
|
42
|
-
return object
|
43
|
-
else
|
44
|
-
raise ArgumentError, "Object must be a Numeric, TrueClass, FalseClass, String, Date, DateTime or Time object. #{object.class.name}:#{object.inspect} given."
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
alias_method(:localize_without_complements, :localize)
|
49
|
-
alias_method(:localize, :localize_with_complements)
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,107 +0,0 @@
|
|
1
|
-
# This module aimed to structure and controls currencies through the application
|
2
|
-
# It represents the international monetary system with all its currencies like specified in ISO 4217
|
3
|
-
# Numisma comes from latin: It designs here the "science of money"
|
4
|
-
require 'net/http'
|
5
|
-
require 'yaml'
|
6
|
-
require 'i18n-complements/numisma/currency'
|
7
|
-
|
8
|
-
module I18nComplements
|
9
|
-
module Numisma
|
10
|
-
|
11
|
-
class << self
|
12
|
-
|
13
|
-
def currencies
|
14
|
-
@@currencies
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
# Returns the path to currencies file
|
19
|
-
def currencies_file
|
20
|
-
# Rails.root.join("config", "currencies.yml")
|
21
|
-
File.join(File.dirname(__FILE__), "numisma", "currencies.yml")
|
22
|
-
end
|
23
|
-
|
24
|
-
# Returns a hash with active currencies only
|
25
|
-
def active_currencies
|
26
|
-
x = {}
|
27
|
-
for code, currency in @@currencies
|
28
|
-
x[code] = currency if currency.active
|
29
|
-
end
|
30
|
-
return x
|
31
|
-
end
|
32
|
-
|
33
|
-
# Shorcut to get currency
|
34
|
-
def [](currency_code)
|
35
|
-
@@currencies[currency_code]
|
36
|
-
end
|
37
|
-
|
38
|
-
def currency_rate(from, to)
|
39
|
-
raise ArgumentError.new(":from currency is unknown (#{from.class}:#{from.inspect})") if Numisma[from].nil?
|
40
|
-
raise ArgumentError.new(":to currency is unknown (#{to.class}:#{to.inspect})") if Numisma[to].nil?
|
41
|
-
rate = nil
|
42
|
-
begin
|
43
|
-
uri = URI("http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate")
|
44
|
-
response = Net::HTTP.post_form(uri, 'FromCurrency' => from, 'ToCurrency' => to)
|
45
|
-
doc = ::LibXML::XML::Parser.string(response.body).parse
|
46
|
-
rate = doc.root.content.to_f
|
47
|
-
rescue
|
48
|
-
uri = URI("http://download.finance.yahoo.com/d/quotes.csv?s=#{from}#{to}=X&f=l1")
|
49
|
-
response = Net::HTTP.get(uri)
|
50
|
-
rate = response.strip.to_f
|
51
|
-
end
|
52
|
-
return rate
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
# Load currencies
|
57
|
-
def load_currencies
|
58
|
-
@@currencies = {}
|
59
|
-
for code, details in YAML.load_file(self.currencies_file)
|
60
|
-
|
61
|
-
currency = Currency.new(code, details.inject({}){|h, p| h[p[0].to_sym] = p[1]; h})
|
62
|
-
@@currencies[currency.code] = currency
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Finally load all currencies
|
68
|
-
load_currencies
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
module ::I18n
|
74
|
-
|
75
|
-
class << self
|
76
|
-
|
77
|
-
def currencies(currency_code)
|
78
|
-
I18nComplements::Numisma.currencies[currency_code.to_s]
|
79
|
-
end
|
80
|
-
|
81
|
-
def active_currencies
|
82
|
-
I18nComplements::Numisma.active_currencies
|
83
|
-
end
|
84
|
-
|
85
|
-
def available_currencies
|
86
|
-
I18nComplements::Numisma.currencies
|
87
|
-
end
|
88
|
-
|
89
|
-
def currency_label(currency_code)
|
90
|
-
if currency = I18nComplements::Numisma.currencies[currency_code.to_s]
|
91
|
-
currency.label
|
92
|
-
else
|
93
|
-
return "Unknown currency: #{currency_code}"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def currency_rate(from, to)
|
98
|
-
I18nComplements::Numisma.currency_rate(from, to)
|
99
|
-
end
|
100
|
-
|
101
|
-
def currencies_file
|
102
|
-
I18nComplements::Numisma.currencies_file
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
|
107
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
module I18nComplements
|
2
|
-
module Numisma
|
3
|
-
|
4
|
-
class Currency
|
5
|
-
attr_reader :code, :active, :cash, :countries, :number, :precision, :unit
|
6
|
-
|
7
|
-
def initialize(code, options = {})
|
8
|
-
@code = code.strip # .upcase
|
9
|
-
@active = (options[:active] ? true : false)
|
10
|
-
@cash = options[:cash].to_a.collect{|x| x.to_f}.sort
|
11
|
-
@countries = options[:countries].to_a.collect{|x| x.to_s}.sort.collect{|x| x.to_sym}
|
12
|
-
@number = options[:number].to_i
|
13
|
-
@precision = options[:precision].to_i
|
14
|
-
@unit = (options[:unit].nil? ? nil : options[:unit].to_s)
|
15
|
-
end
|
16
|
-
|
17
|
-
def name
|
18
|
-
::I18n.translate("currencies.#{self.code}")
|
19
|
-
end
|
20
|
-
|
21
|
-
def label
|
22
|
-
::I18n.translate("labels.currency_with_code", :code=>self.code, :name=>self.name, :default=>"%{name} (%{code})")
|
23
|
-
end
|
24
|
-
|
25
|
-
def round(value, options={})
|
26
|
-
precision = self.precision
|
27
|
-
if RUBY_VERSION.match(/^1\.8/)
|
28
|
-
magnitude = 10**precision
|
29
|
-
return (value * magnitude).to_i.to_f*magnitude
|
30
|
-
else
|
31
|
-
return value.round(precision)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def ==(other_currency)
|
36
|
-
self.code == other_currency.code
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_currency
|
40
|
-
self
|
41
|
-
end
|
42
|
-
|
43
|
-
# Produces a amount of the currency with the locale parameters
|
44
|
-
# TODO: Find a better way to specify number formats which are more complex that the default Rails use
|
45
|
-
def localize(amount, options={})
|
46
|
-
return unless amount
|
47
|
-
|
48
|
-
# options.symbolize_keys!
|
49
|
-
|
50
|
-
defaults = I18n.translate('number.format'.to_sym, :locale => options[:locale], :default => {})
|
51
|
-
defaultt = I18n.translate('number.currency.format'.to_sym, :locale => options[:locale], :default => {})
|
52
|
-
defaultt[:negative_format] ||= ("-" + defaultt[:format]) if defaultt[:format]
|
53
|
-
formatcy = I18n.translate("number.currency.formats.#{self.code}".to_sym, :locale => options[:locale], :default => {})
|
54
|
-
formatcy[:negative_format] ||= "-" + formatcy[:format] if formatcy[:format]
|
55
|
-
|
56
|
-
formatter = {}
|
57
|
-
formatter[:separator] = formatcy[:separator] || defaultt[:separator] || defaults[:separator] || ','
|
58
|
-
formatter[:delimiter] = formatcy[:delimiter] || defaultt[:delimiter] || defaults[:delimiter] || ''
|
59
|
-
formatter[:precision] = formatcy[:precision] || self.precision || defaultt[:precision] || 3
|
60
|
-
format = formatcy[:format] || defaultt[:format] || "%n-%u" # defaults[:format] ||
|
61
|
-
negative_format = formatcy[:negative_format] || defaultt[:negative_format] || defaults[:negative_format] || "-" + format
|
62
|
-
unit = formatcy[:unit] || self.unit || self.code
|
63
|
-
|
64
|
-
if amount.to_f < 0
|
65
|
-
format = negative_format # options.delete(:negative_format)
|
66
|
-
amount = amount.respond_to?("abs") ? amount.abs : amount.sub(/^-/, '')
|
67
|
-
end
|
68
|
-
|
69
|
-
value = amount.to_s
|
70
|
-
integers, decimals = value.split(/\./)
|
71
|
-
value = integers.gsub(/^0+[1-9]+/, '').gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{formatter[:delimiter]}")
|
72
|
-
unless decimals.to_s.match(/^\s*$/)
|
73
|
-
value << formatter[:separator]
|
74
|
-
value << decimals.gsub(/0+$/, '').ljust(formatter[:precision], '0').scan(/.{1,3}/).join(formatter[:delimiter])
|
75
|
-
end
|
76
|
-
return format.gsub(/%n/, value).gsub(/%u/, unit).gsub(/%s/, "\u{00A0}")
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|