i18n-complements 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,10 @@
1
+ require 'i18n'
2
+ require 'i18n-complements/numisma'
3
+ require 'i18n-complements/localize_numbers'
4
+
5
+ module I18nComplements
6
+
7
+ class InvalidCurrency < ArgumentError
8
+ end
9
+
10
+ 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,10 @@
1
+ eng:
2
+ number:
3
+ format:
4
+ separator: '.'
5
+ delimiter: ','
6
+ precision: 3
7
+ currency:
8
+ format:
9
+ format: "%u%n"
10
+ precision: 2
@@ -0,0 +1,10 @@
1
+ fra:
2
+ number:
3
+ format:
4
+ separator: ','
5
+ delimiter: '%s'
6
+ precision: 3
7
+ currency:
8
+ format:
9
+ format: "%n%s%u"
10
+ precision: 2
@@ -0,0 +1,13 @@
1
+ jpn:
2
+ number:
3
+ format:
4
+ separator: '.'
5
+ delimiter: ','
6
+ precision: 3
7
+ currency:
8
+ format:
9
+ format: "%n%u"
10
+ precision: 2
11
+ formats:
12
+ JPY:
13
+ unit: "円"
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+
3
+ class TestCurrencies < Test::Unit::TestCase
4
+
5
+ def test_listing_of_currencies
6
+ end
7
+
8
+
9
+ def test_currency_rates
10
+ end
11
+
12
+ 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: