i18n-complements 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +15 -0
- data/VERSION +1 -0
- data/lib/i18n-complements/localize_numbers.rb +65 -0
- data/lib/i18n-complements/numisma/currencies.yml +1002 -0
- data/lib/i18n-complements/numisma/currency.rb +78 -0
- data/lib/i18n-complements/numisma.rb +61 -0
- data/lib/i18n-complements.rb +10 -0
- data/test/helper.rb +11 -0
- data/test/locales/eng.yml +10 -0
- data/test/locales/fra.yml +10 -0
- data/test/locales/jpn.yml +13 -0
- data/test/test_currencies.rb +12 -0
- data/test/test_numbers.rb +84 -0
- metadata +86 -0
@@ -0,0 +1,78 @@
|
|
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
|
+
# Produces a amount of the currency with the locale parameters
|
40
|
+
# TODO: Find a better way to specify number formats which are more complex that the default Rails use
|
41
|
+
def localize(amount, options={})
|
42
|
+
return unless amount
|
43
|
+
|
44
|
+
# options.symbolize_keys!
|
45
|
+
|
46
|
+
defaults = I18n.translate('number.format'.to_sym, :locale => options[:locale], :default => {})
|
47
|
+
defaultt = I18n.translate('number.currency.format'.to_sym, :locale => options[:locale], :default => {})
|
48
|
+
defaultt[:negative_format] ||= ("-" + defaultt[:format]) if defaultt[:format]
|
49
|
+
formatcy = I18n.translate("number.currency.formats.#{self.code}".to_sym, :locale => options[:locale], :default => {})
|
50
|
+
formatcy[:negative_format] ||= "-" + formatcy[:format] if formatcy[:format]
|
51
|
+
|
52
|
+
prec = {}
|
53
|
+
prec[:separator] = formatcy[:separator] || defaultt[:separator] || defaults[:separator] || ','
|
54
|
+
prec[:delimiter] = formatcy[:delimiter] || defaultt[:delimiter] || defaults[:delimiter] || ''
|
55
|
+
prec[:precision] = formatcy[:precision] || self.precision || defaultt[:precision] || 3
|
56
|
+
format = formatcy[:format] || defaultt[:format] || "%n-%u" # defaults[:format] ||
|
57
|
+
negative_format = formatcy[:negative_format] || defaultt[:negative_format] || defaults[:negative_format] || "-" + format
|
58
|
+
unit = formatcy[:unit] || self.unit || self.code
|
59
|
+
|
60
|
+
if amount.to_f < 0
|
61
|
+
format = negative_format # options.delete(:negative_format)
|
62
|
+
amount = amount.respond_to?("abs") ? amount.abs : amount.sub(/^-/, '')
|
63
|
+
end
|
64
|
+
|
65
|
+
value = amount.to_s
|
66
|
+
integers, decimals = value.split(/\./)
|
67
|
+
value = integers.gsub(/^0+[1-9]+/, '').gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{prec[:delimiter]}")
|
68
|
+
unless decimals.to_s.match(/^\s*$/)
|
69
|
+
decimals = decimals.gsub(/0+$/, '').ljust(prec[:precision], '0').reverse.split(/(?=\d{3})/).reverse.collect{|x| x.reverse}.join(prec[:delimiter])
|
70
|
+
value += prec[:separator] + decimals
|
71
|
+
end
|
72
|
+
return format.gsub(/%n/, value).gsub(/%u/, unit).gsub(/%s/, "\u{00A0}")
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,61 @@
|
|
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 'i18n-complements/numisma/currency'
|
6
|
+
|
7
|
+
module I18nComplements
|
8
|
+
module Numisma
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def currencies
|
13
|
+
@@currencies
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Returns the path to currencies file
|
18
|
+
def currencies_file
|
19
|
+
# Rails.root.join("config", "currencies.yml")
|
20
|
+
File.join(File.dirname(__FILE__), "numisma", "currencies.yml")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a hash with active currencies only
|
24
|
+
def active_currencies
|
25
|
+
x = {}
|
26
|
+
for code, currency in @@currencies
|
27
|
+
x[code] = currency if currency.active
|
28
|
+
end
|
29
|
+
return x
|
30
|
+
end
|
31
|
+
|
32
|
+
# Shorcut to get currency
|
33
|
+
def [](currency_code)
|
34
|
+
@@currencies[currency_code]
|
35
|
+
end
|
36
|
+
|
37
|
+
def currency_rate(from, to)
|
38
|
+
raise ArgumentError.new(":from currency is unknown (#{from.class}:#{from.inspect})") if Numisma[from].nil?
|
39
|
+
raise ArgumentError.new(":to currency is unknown (#{to.class}:#{to.inspect})") if Numisma[to].nil?
|
40
|
+
uri = URI("http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate")
|
41
|
+
response = Net::HTTP.post_form(uri, 'FromCurrency' => from, 'ToCurrency' => to)
|
42
|
+
doc = ::LibXML::XML::Parser.string(response.body).parse
|
43
|
+
return doc.root.content.to_f
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Load currencies
|
48
|
+
def load_currencies
|
49
|
+
@@currencies = {}
|
50
|
+
for code, details in YAML.load_file(self.currencies_file)
|
51
|
+
|
52
|
+
currency = Currency.new(code, details.inject({}){|h, p| h[p[0].to_sym] = p[1]; h})
|
53
|
+
@@currencies[currency.code] = currency
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Finally load all currencies
|
59
|
+
load_currencies
|
60
|
+
end
|
61
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
|
7
|
+
require 'i18n-complements'
|
8
|
+
|
9
|
+
for file in Dir[File.join(File.dirname(__FILE__), "locales", "*.yml")]
|
10
|
+
I18n.backend.load_translations(file)
|
11
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
class TestNumbers < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_localization
|
7
|
+
assert_nothing_raised do
|
8
|
+
I18n.localize(14.5)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_number_formatting
|
13
|
+
# Integer
|
14
|
+
number = 3
|
15
|
+
assert_equal "3", I18n.localize(number, :locale => :eng)
|
16
|
+
assert_equal "3", I18n.localize(number, :locale => :fra)
|
17
|
+
|
18
|
+
# Integer > 1000
|
19
|
+
number = 21145
|
20
|
+
assert_equal "21,145", I18n.localize(number, :locale => :eng)
|
21
|
+
assert_equal "21\u{00A0}145", I18n.localize(number, :locale => :fra)
|
22
|
+
|
23
|
+
# Float without integers with decimals
|
24
|
+
number = 0.5
|
25
|
+
assert_equal "0.500", I18n.localize(number, :locale => :eng)
|
26
|
+
assert_equal "0,500", I18n.localize(number, :locale => :fra)
|
27
|
+
|
28
|
+
# Float without decimals
|
29
|
+
number = 3.0
|
30
|
+
assert_equal "3.000", I18n.localize(number, :locale => :eng)
|
31
|
+
assert_equal "3,000", I18n.localize(number, :locale => :fra)
|
32
|
+
|
33
|
+
# Float
|
34
|
+
number = 14.53
|
35
|
+
assert_equal "14.530", I18n.localize(number, :locale => :eng)
|
36
|
+
assert_equal "14,530", I18n.localize(number, :locale => :fra)
|
37
|
+
|
38
|
+
# Float > 1000
|
39
|
+
number = 2114.5
|
40
|
+
assert_equal "2,114.500", I18n.localize(number, :locale => :eng)
|
41
|
+
assert_equal "2\u{00A0}114,500", I18n.localize(number, :locale => :fra)
|
42
|
+
|
43
|
+
# Float without integers with decimals < 0.001
|
44
|
+
number = 0.41421356
|
45
|
+
assert_equal "0.414,213,56", I18n.localize(number, :locale => :eng)
|
46
|
+
assert_equal "0,414\u{00A0}213\u{00A0}56", I18n.localize(number, :locale => :fra)
|
47
|
+
|
48
|
+
# Float without integers with decimals < 0.001
|
49
|
+
number = 3.1415926
|
50
|
+
assert_equal "3.141,592,6", I18n.localize(number, :locale => :eng)
|
51
|
+
assert_equal "3,141\u{00A0}592\u{00A0}6", I18n.localize(number, :locale => :fra)
|
52
|
+
|
53
|
+
# Float without integers with decimals < 0.001
|
54
|
+
number = 62951413.1415926
|
55
|
+
assert_equal "62,951,413.141,592,6", I18n.localize(number, :locale => :eng)
|
56
|
+
assert_equal "62\u{00A0}951\u{00A0}413,141\u{00A0}592\u{00A0}6", I18n.localize(number, :locale => :fra)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def test_localization_with_currency
|
61
|
+
I18n.localize(14.5, :currency => :JPY)
|
62
|
+
assert_nothing_raised do
|
63
|
+
I18n.localize(14.5, :currency => :JPY)
|
64
|
+
end
|
65
|
+
|
66
|
+
assert_nothing_raised do
|
67
|
+
I18n.localize(14.5, :currency => "JPY")
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_raise(I18nComplements::InvalidCurrency) do
|
71
|
+
I18n.localize(14.5, :currency => "jPY")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_formatting_with_currency
|
76
|
+
number = 413500
|
77
|
+
assert_equal "¥413,500", I18n.localize(number, :locale => :eng, :currency=>"JPY")
|
78
|
+
assert_equal "413\u{00A0}500\u{00A0}¥", I18n.localize(number, :locale => :fra, :currency=>"JPY")
|
79
|
+
assert_equal "413,500円", I18n.localize(number, :locale => :jpn, :currency=>"JPY")
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: i18n-complements
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brice Texier
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-09 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: i18n
|
16
|
+
requirement: &15085180 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *15085180
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &15084120 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.8.7
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *15084120
|
36
|
+
description:
|
37
|
+
email: burisu@oneiros.fr
|
38
|
+
executables: []
|
39
|
+
extensions: []
|
40
|
+
extra_rdoc_files:
|
41
|
+
- LICENSE
|
42
|
+
- README
|
43
|
+
files:
|
44
|
+
- LICENSE
|
45
|
+
- README
|
46
|
+
- VERSION
|
47
|
+
- lib/i18n-complements.rb
|
48
|
+
- lib/i18n-complements/localize_numbers.rb
|
49
|
+
- lib/i18n-complements/numisma.rb
|
50
|
+
- lib/i18n-complements/numisma/currencies.yml
|
51
|
+
- lib/i18n-complements/numisma/currency.rb
|
52
|
+
- test/helper.rb
|
53
|
+
- test/locales/eng.yml
|
54
|
+
- test/locales/fra.yml
|
55
|
+
- test/locales/jpn.yml
|
56
|
+
- test/test_currencies.rb
|
57
|
+
- test/test_numbers.rb
|
58
|
+
homepage: http://github.com/burisu/i18n-complements
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.11
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: I18n missing functionnalities
|
83
|
+
test_files:
|
84
|
+
- test/test_currencies.rb
|
85
|
+
- test/test_numbers.rb
|
86
|
+
has_rdoc:
|