i18n-complements 0.0.1

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.
@@ -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: