currency_exchange 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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +20 -0
- data/currency_exchange.gemspec +27 -0
- data/lib/currency_exchange/data/currencies.rb +176 -0
- data/lib/currency_exchange/exchangers/open_exchange.rb +21 -0
- data/lib/currency_exchange/ext/fixnum.rb +22 -0
- data/lib/currency_exchange/storage/cache.rb +31 -0
- data/lib/currency_exchange/storage/mem_cache.rb +19 -0
- data/lib/currency_exchange/transporters/exchange_transporter.rb +29 -0
- data/lib/currency_exchange/version.rb +3 -0
- data/lib/currency_exchange.rb +36 -0
- data/spec/data/currencies_spec.rb +35 -0
- data/spec/exchangers/open_exchange_spec.rb +70 -0
- data/spec/ext/fixnum_spec.rb +49 -0
- data/spec/spec_helper.rb +8 -0
- metadata +157 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'bundler'
|
10
|
+
Bundler::GemHelper.install_tasks
|
11
|
+
|
12
|
+
require 'rake'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
desc "Run all examples"
|
16
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
17
|
+
t.rspec_opts = %w[--color]
|
18
|
+
end
|
19
|
+
|
20
|
+
task :default => [:spec]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "currency_exchange/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "currency_exchange"
|
7
|
+
s.version = CurrencyExchange::VERSION
|
8
|
+
s.authors = ["Thil Bandara"]
|
9
|
+
s.email = ["tbandara@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/thil/currency_exchange"
|
11
|
+
s.summary = %q{A basic library to retrieve and convert currency}
|
12
|
+
s.description = %q{A basic library to retrieve and convert currency}
|
13
|
+
|
14
|
+
s.rubyforge_project = "currency_exchange"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_runtime_dependency "rest-client"
|
24
|
+
s.add_runtime_dependency "json"
|
25
|
+
s.add_runtime_dependency "activesupport", ">= 3.2.0"
|
26
|
+
s.add_runtime_dependency "rails", ">= 3.2.0"
|
27
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module CurrencyExchange
|
2
|
+
module Data
|
3
|
+
class Currencies
|
4
|
+
|
5
|
+
def self.has_currency?(from, to)
|
6
|
+
return false unless from && to
|
7
|
+
CURRENCIES.has_key?(from.upcase) && CURRENCIES.has_key?(to.upcase)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
CURRENCIES = {
|
13
|
+
"AED"=> "United Arab Emirates Dirham",
|
14
|
+
"AFN"=> "Afghan Afghani",
|
15
|
+
"ALL"=> "Albanian Lek",
|
16
|
+
"AMD"=> "Armenian Dram",
|
17
|
+
"ANG"=> "Netherlands Antillean Guilder",
|
18
|
+
"AOA"=> "Angolan Kwanza",
|
19
|
+
"ARS"=> "Argentine Peso",
|
20
|
+
"AUD"=> "Australian Dollar",
|
21
|
+
"AWG"=> "Aruban Florin",
|
22
|
+
"AZN"=> "Azerbaijani Manat",
|
23
|
+
"BAM"=> "Bosnia-Herzegovina Convertible Mark",
|
24
|
+
"BBD"=> "Barbadian Dollar",
|
25
|
+
"BDT"=> "Bangladeshi Taka",
|
26
|
+
"BGN"=> "Bulgarian Lev",
|
27
|
+
"BHD"=> "Bahraini Dinar",
|
28
|
+
"BIF"=> "Burundian Franc",
|
29
|
+
"BMD"=> "Bermudan Dollar",
|
30
|
+
"BND"=> "Brunei Dollar",
|
31
|
+
"BOB"=> "Bolivian Boliviano",
|
32
|
+
"BRL"=> "Brazilian Real",
|
33
|
+
"BSD"=> "Bahamian Dollar",
|
34
|
+
"BTN"=> "Bhutanese Ngultrum",
|
35
|
+
"BWP"=> "Botswanan Pula",
|
36
|
+
"BYR"=> "Belarusian Ruble",
|
37
|
+
"BZD"=> "Belize Dollar",
|
38
|
+
"CAD"=> "Canadian Dollar",
|
39
|
+
"CDF"=> "Congolese Franc",
|
40
|
+
"CHF"=> "Swiss Franc",
|
41
|
+
"CLF"=> "Chilean Unit of Account (UF)",
|
42
|
+
"CLP"=> "Chilean Peso",
|
43
|
+
"CNY"=> "Chinese Yuan",
|
44
|
+
"COP"=> "Colombian Peso",
|
45
|
+
"CRC"=> "Costa Rican Colon",
|
46
|
+
"CUP"=> "Cuban Peso",
|
47
|
+
"CVE"=> "Cape Verdean Escudo",
|
48
|
+
"CZK"=> "Czech Republic Koruna",
|
49
|
+
"DJF"=> "Djiboutian Franc",
|
50
|
+
"DKK"=> "Danish Krone",
|
51
|
+
"DOP"=> "Dominican Peso",
|
52
|
+
"DZD"=> "Algerian Dinar",
|
53
|
+
"EGP"=> "Egyptian Pound",
|
54
|
+
"ETB"=> "Ethiopian Birr",
|
55
|
+
"EUR"=> "Euro",
|
56
|
+
"FJD"=> "Fijian Dollar",
|
57
|
+
"FKP"=> "Falkland Islands Pound",
|
58
|
+
"GBP"=> "British Pound Sterling",
|
59
|
+
"GEL"=> "Georgian Lari",
|
60
|
+
"GHS"=> "Ghanaian Cedi",
|
61
|
+
"GIP"=> "Gibraltar Pound",
|
62
|
+
"GMD"=> "Gambian Dalasi",
|
63
|
+
"GNF"=> "Guinean Franc",
|
64
|
+
"GTQ"=> "Guatemalan Quetzal",
|
65
|
+
"GYD"=> "Guyanaese Dollar",
|
66
|
+
"HKD"=> "Hong Kong Dollar",
|
67
|
+
"HNL"=> "Honduran Lempira",
|
68
|
+
"HRK"=> "Croatian Kuna",
|
69
|
+
"HTG"=> "Haitian Gourde",
|
70
|
+
"HUF"=> "Hungarian Forint",
|
71
|
+
"IDR"=> "Indonesian Rupiah",
|
72
|
+
"IEP"=> "Irish Pound",
|
73
|
+
"ILS"=> "Israeli New Sheqel",
|
74
|
+
"INR"=> "Indian Rupee",
|
75
|
+
"IQD"=> "Iraqi Dinar",
|
76
|
+
"IRR"=> "Iranian Rial",
|
77
|
+
"ISK"=> "Icelandic Krona",
|
78
|
+
"JMD"=> "Jamaican Dollar",
|
79
|
+
"JOD"=> "Jordanian Dinar",
|
80
|
+
"JPY"=> "Japanese Yen",
|
81
|
+
"KES"=> "Kenyan Shilling",
|
82
|
+
"KGS"=> "Kyrgystani Som",
|
83
|
+
"KHR"=> "Cambodian Riel",
|
84
|
+
"KMF"=> "Comorian Franc",
|
85
|
+
"KPW"=> "North Korean Won",
|
86
|
+
"KRW"=> "South Korean Won",
|
87
|
+
"KWD"=> "Kuwaiti Dinar",
|
88
|
+
"KZT"=> "Kazakhstani Tenge",
|
89
|
+
"LAK"=> "Laotian Kip",
|
90
|
+
"LBP"=> "Lebanese Pound",
|
91
|
+
"LKR"=> "Sri Lankan Rupee",
|
92
|
+
"LRD"=> "Liberian Dollar",
|
93
|
+
"LSL"=> "Lesotho Loti",
|
94
|
+
"LTL"=> "Lithuanian Litas",
|
95
|
+
"LVL"=> "Latvian Lats",
|
96
|
+
"LYD"=> "Libyan Dinar",
|
97
|
+
"MAD"=> "Moroccan Dirham",
|
98
|
+
"MDL"=> "Moldovan Leu",
|
99
|
+
"MGA"=> "Malagasy Ariary",
|
100
|
+
"MKD"=> "Macedonian Denar",
|
101
|
+
"MMK"=> "Myanma Kyat",
|
102
|
+
"MNT"=> "Mongolian Tugrik",
|
103
|
+
"MOP"=> "Macanese Pataca",
|
104
|
+
"MRO"=> "Mauritanian Ouguiya",
|
105
|
+
"MUR"=> "Mauritian Rupee",
|
106
|
+
"MVR"=> "Maldivian Rufiyaa",
|
107
|
+
"MWK"=> "Malawian Kwacha",
|
108
|
+
"MXN"=> "Mexican Peso",
|
109
|
+
"MYR"=> "Malaysian Ringgit",
|
110
|
+
"MZN"=> "Mozambican Metical",
|
111
|
+
"NAD"=> "Namibian Dollar",
|
112
|
+
"NGN"=> "Nigerian Naira",
|
113
|
+
"NIO"=> "Nicaraguan Cordoba",
|
114
|
+
"NOK"=> "Norwegian Krone",
|
115
|
+
"NPR"=> "Nepalese Rupee",
|
116
|
+
"NZD"=> "New Zealand Dollar",
|
117
|
+
"OMR"=> "Omani Rial",
|
118
|
+
"PAB"=> "Panamanian Balboa",
|
119
|
+
"PEN"=> "Peruvian Nuevo Sol",
|
120
|
+
"PGK"=> "Papua New Guinean Kina",
|
121
|
+
"PHP"=> "Philippine Peso",
|
122
|
+
"PKR"=> "Pakistani Rupee",
|
123
|
+
"PLN"=> "Polish Zloty",
|
124
|
+
"PYG"=> "Paraguayan Guarani",
|
125
|
+
"QAR"=> "Qatari Rial",
|
126
|
+
"RON"=> "Romanian Leu",
|
127
|
+
"RSD"=> "Serbian Dinar",
|
128
|
+
"RUB"=> "Russian Ruble",
|
129
|
+
"RWF"=> "Rwandan Franc",
|
130
|
+
"SAR"=> "Saudi Riyal",
|
131
|
+
"SBD"=> "Solomon Islands Dollar",
|
132
|
+
"SCR"=> "Seychellois Rupee",
|
133
|
+
"SDG"=> "Sudanese Pound",
|
134
|
+
"SEK"=> "Swedish Krona",
|
135
|
+
"SGD"=> "Singapore Dollar",
|
136
|
+
"SHP"=> "Saint Helena Pound",
|
137
|
+
"SLL"=> "Sierra Leonean Leone",
|
138
|
+
"SOS"=> "Somali Shilling",
|
139
|
+
"SRD"=> "Surinamese Dollar",
|
140
|
+
"STD"=> "Sao Tome and Principe Dobra",
|
141
|
+
"SVC"=> "Salvadoran Colon",
|
142
|
+
"SYP"=> "Syrian Pound",
|
143
|
+
"SZL"=> "Swazi Lilangeni",
|
144
|
+
"THB"=> "Thai Baht",
|
145
|
+
"TJS"=> "Tajikistani Somoni",
|
146
|
+
"TMT"=> "Turkmenistani Manat",
|
147
|
+
"TND"=> "Tunisian Dinar",
|
148
|
+
"TOP"=> "Tongan Pa anga",
|
149
|
+
"TRY"=> "Turkish Lira",
|
150
|
+
"TTD"=> "Trinidad and Tobago Dollar",
|
151
|
+
"TWD"=> "New Taiwan Dollar",
|
152
|
+
"TZS"=> "Tanzanian Shilling",
|
153
|
+
"UAH"=> "Ukrainian Hryvnia",
|
154
|
+
"UGX"=> "Ugandan Shilling",
|
155
|
+
"USD"=> "United States Dollar",
|
156
|
+
"UYU"=> "Uruguayan Peso",
|
157
|
+
"UZS"=> "Uzbekistan Som",
|
158
|
+
"VEF"=> "Venezuelan Bolivar",
|
159
|
+
"VND"=> "Vietnamese Dong",
|
160
|
+
"VUV"=> "Vanuatu Vatu",
|
161
|
+
"WST"=> "Samoan Tala",
|
162
|
+
"XAF"=> "CFA Franc BEAC",
|
163
|
+
"XCD"=> "East Caribbean Dollar",
|
164
|
+
"XDR"=> "Special Drawing Rights",
|
165
|
+
"XOF"=> "CFA Franc BCEAO",
|
166
|
+
"XPF"=> "CFP Franc",
|
167
|
+
"YER"=> "Yemeni Rial",
|
168
|
+
"ZAR"=> "South African Rand",
|
169
|
+
"ZMK"=> "Zambian Kwacha",
|
170
|
+
"ZWD"=> "Zimbabwean Dollar (1980-2008)",
|
171
|
+
"ZWL"=> "Zimbabwean Dollar"
|
172
|
+
}
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CurrencyExchange
|
2
|
+
class Exchangers::OpenExchange
|
3
|
+
|
4
|
+
LATEST_EXCHANGE_URL = "http://openexchangerates.org/latest.json"
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@transporter = CurrencyExchange::Transporters::ExchangeTransporter.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def convert(number, from, to)
|
11
|
+
number * rates[to.upcase] * ( 1 / rates[from.upcase] ) if rates[to.upcase] && rates[from.upcase]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def rates
|
17
|
+
@rates ||= @transporter.retrieve_rates(LATEST_EXCHANGE_URL)['rates']
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Numeric
|
2
|
+
UNABLE_TO_EXCHANGE = "Unable to exchange"
|
3
|
+
|
4
|
+
def exchange(from, to)
|
5
|
+
exchange = CurrencyExchange.convert(self, from, to)
|
6
|
+
exchange ? "$%.2f" % exchange : UNABLE_TO_EXCHANGE
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(sym, *args, &block)
|
10
|
+
empty, from, to = currency_string(sym)
|
11
|
+
if CurrencyExchange.has_currency?(from, to)
|
12
|
+
return exchange(from, to)
|
13
|
+
else
|
14
|
+
super.method_missing(sym, *args, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def currency_string(method)
|
20
|
+
method.to_s.split /(.+)_to_(.+)/
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CurrencyExchange
|
2
|
+
class Storage::Cache
|
3
|
+
|
4
|
+
class << self
|
5
|
+
attr_accessor :cache_strategy
|
6
|
+
|
7
|
+
def instance
|
8
|
+
@instance ||= load_instance
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def store(key, value)
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def self.load_instance
|
22
|
+
if self.cache_strategy == :memcache
|
23
|
+
CurrencyExchange::Storage::MemCache.new
|
24
|
+
else
|
25
|
+
self.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
begin
|
2
|
+
require 'rails'
|
3
|
+
rescue LoadError
|
4
|
+
raise "You don't have rails installed"
|
5
|
+
end
|
6
|
+
|
7
|
+
module CurrencyExchange
|
8
|
+
class Storage::MemCache < Storage::Cache
|
9
|
+
|
10
|
+
def fetch(key)
|
11
|
+
Rails.cache.read(key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def store(key, value)
|
15
|
+
Rails.cache.write(key, value, :expires_in => 1.day)
|
16
|
+
value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
begin
|
2
|
+
require 'rest-client'
|
3
|
+
require 'json'
|
4
|
+
rescue LoadError
|
5
|
+
raise "You don't have the required gems installed"
|
6
|
+
end
|
7
|
+
|
8
|
+
module CurrencyExchange
|
9
|
+
module Transporters
|
10
|
+
class ExchangeTransporter
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@storage = CurrencyExchange::Storage::Cache.instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def retrieve_rates(url)
|
17
|
+
@storage.fetch(url) || @storage.store(url, fetch_json(url))
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def fetch_json(url)
|
23
|
+
response = RestClient.get(url, {:accept => :json})
|
24
|
+
JSON.parse(response.body)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "currency_exchange/version"
|
2
|
+
require 'currency_exchange/ext/fixnum'
|
3
|
+
|
4
|
+
module CurrencyExchange
|
5
|
+
module Exchangers
|
6
|
+
autoload :OpenExchange, 'currency_exchange/exchangers/open_exchange'
|
7
|
+
end
|
8
|
+
|
9
|
+
module Transporters
|
10
|
+
autoload :ExchangeTransporter, 'currency_exchange/transporters/exchange_transporter'
|
11
|
+
end
|
12
|
+
|
13
|
+
module Data
|
14
|
+
autoload :Currencies, 'currency_exchange/data/currencies'
|
15
|
+
end
|
16
|
+
|
17
|
+
module Storage
|
18
|
+
autoload :Cache, 'currency_exchange/storage/cache'
|
19
|
+
autoload :MemCache, 'currency_exchange/storage/mem_cache'
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def convert(number, from, to)
|
24
|
+
exchanger.convert(number, from, to) if has_currency?(from, to)
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_currency?(from, to)
|
28
|
+
CurrencyExchange::Data::Currencies.has_currency?(from, to)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def exchanger
|
33
|
+
@exchanger ||= CurrencyExchange::Exchangers::OpenExchange.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CurrencyExchange::Data::Currencies do
|
4
|
+
|
5
|
+
describe "#has_currency?" do
|
6
|
+
let(:from) { "USD" }
|
7
|
+
let(:to) { "AUD" }
|
8
|
+
subject { CurrencyExchange::Data::Currencies.has_currency?(from, to) }
|
9
|
+
|
10
|
+
context "when from currency is nil" do
|
11
|
+
let(:from) { nil }
|
12
|
+
it { should == false }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when to currency is nil" do
|
16
|
+
let(:to) { nil }
|
17
|
+
it { subject.should == false }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when from currency does not exist in currencies list" do
|
21
|
+
let(:from) { "EEE" }
|
22
|
+
it { subject.should == false }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when to currency does not exist in currencies list" do
|
26
|
+
let(:to) { "EEE" }
|
27
|
+
it { subject.should == false }
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return true when from and to currencies exist" do
|
31
|
+
subject.should == true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CurrencyExchange::Exchangers::OpenExchange do
|
4
|
+
|
5
|
+
describe "#convert" do
|
6
|
+
let(:aud) { "AUD" }
|
7
|
+
let(:aud_rate) { 4 }
|
8
|
+
let(:usd) { "USD" }
|
9
|
+
let(:usd_rate) { 2 }
|
10
|
+
let(:rates) { { aud => aud_rate, usd => usd_rate } }
|
11
|
+
let(:number) { 10 }
|
12
|
+
let(:calculated_rate) { number * usd_rate * ( 1 / aud_rate ) }
|
13
|
+
let(:open_exchange) { CurrencyExchange::Exchangers::OpenExchange.new }
|
14
|
+
|
15
|
+
subject { open_exchange.convert(number, aud, usd) }
|
16
|
+
|
17
|
+
before do
|
18
|
+
open_exchange.stub(:rates).and_return(rates)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return exchanged rate" do
|
22
|
+
subject.should == calculated_rate
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when from/to country code is lowercase" do
|
26
|
+
subject { open_exchange.convert(number, "aud", "usd") }
|
27
|
+
|
28
|
+
it "should return exchanged rate" do
|
29
|
+
subject.should == calculated_rate
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when country code is not in rates" do
|
34
|
+
subject { open_exchange.convert(number, "ad", "usd") }
|
35
|
+
|
36
|
+
it { should == nil }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#rates" do
|
41
|
+
let(:url) { CurrencyExchange::Exchangers::OpenExchange::LATEST_EXCHANGE_URL }
|
42
|
+
let(:rates) { { "AED" => 3.1 } }
|
43
|
+
let(:data) { { "disclaimer" => 'abc', "rates" => rates } }
|
44
|
+
let(:transporter) { mock(CurrencyExchange::Transporters::ExchangeTransporter, :retrieve_rates => data) }
|
45
|
+
let(:open_exchange) { CurrencyExchange::Exchangers::OpenExchange.new }
|
46
|
+
|
47
|
+
subject { open_exchange.send(:rates) }
|
48
|
+
|
49
|
+
before do
|
50
|
+
CurrencyExchange::Transporters::ExchangeTransporter.stub(:new).and_return(transporter)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should call transporter" do
|
54
|
+
transporter.should_receive(:retrieve_rates).with(url)
|
55
|
+
subject
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should retrieve rates from data" do
|
59
|
+
subject.should == rates
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when data is empty" do
|
63
|
+
let(:data) { {} }
|
64
|
+
|
65
|
+
it { should == nil }
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Numeric do
|
4
|
+
|
5
|
+
describe "#exchange" do
|
6
|
+
let(:number) { 10 }
|
7
|
+
let(:converted) { 3 }
|
8
|
+
let(:from) { "USD" }
|
9
|
+
let(:to) { "AUD" }
|
10
|
+
|
11
|
+
subject { number.exchange(from, to) }
|
12
|
+
|
13
|
+
before do
|
14
|
+
CurrencyExchange.stub(:convert).with(number, from, to).and_return(converted)
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when converted value is nil" do
|
18
|
+
let(:converted) { nil }
|
19
|
+
it "should return unable to exchange" do
|
20
|
+
subject.should == Numeric::UNABLE_TO_EXCHANGE
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should convert exchange value into dollar decimals" do
|
25
|
+
subject.should == "$%.2f" % converted
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#currency_to_currency" do
|
30
|
+
let(:aud) { "aud" }
|
31
|
+
let(:usd) { "usd" }
|
32
|
+
let(:number) { 10 }
|
33
|
+
|
34
|
+
subject { number.aud_to_usd }
|
35
|
+
|
36
|
+
it "should call exchange with usd and aud" do
|
37
|
+
CurrencyExchange.should_receive(:convert).with(number, aud, usd)
|
38
|
+
subject
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when currency doesnt exist" do
|
42
|
+
subject { number.au_to_usd }
|
43
|
+
it "should throw no method exception" do
|
44
|
+
expect{subject}.to raise_error(NoMethodError)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: currency_exchange
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Thil Bandara
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-02-13 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rest-client
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: json
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activesupport
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 15
|
71
|
+
segments:
|
72
|
+
- 3
|
73
|
+
- 2
|
74
|
+
- 0
|
75
|
+
version: 3.2.0
|
76
|
+
type: :runtime
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rails
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 15
|
87
|
+
segments:
|
88
|
+
- 3
|
89
|
+
- 2
|
90
|
+
- 0
|
91
|
+
version: 3.2.0
|
92
|
+
type: :runtime
|
93
|
+
version_requirements: *id005
|
94
|
+
description: A basic library to retrieve and convert currency
|
95
|
+
email:
|
96
|
+
- tbandara@gmail.com
|
97
|
+
executables: []
|
98
|
+
|
99
|
+
extensions: []
|
100
|
+
|
101
|
+
extra_rdoc_files: []
|
102
|
+
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- Gemfile
|
106
|
+
- Rakefile
|
107
|
+
- currency_exchange.gemspec
|
108
|
+
- lib/currency_exchange.rb
|
109
|
+
- lib/currency_exchange/data/currencies.rb
|
110
|
+
- lib/currency_exchange/exchangers/open_exchange.rb
|
111
|
+
- lib/currency_exchange/ext/fixnum.rb
|
112
|
+
- lib/currency_exchange/storage/cache.rb
|
113
|
+
- lib/currency_exchange/storage/mem_cache.rb
|
114
|
+
- lib/currency_exchange/transporters/exchange_transporter.rb
|
115
|
+
- lib/currency_exchange/version.rb
|
116
|
+
- spec/data/currencies_spec.rb
|
117
|
+
- spec/exchangers/open_exchange_spec.rb
|
118
|
+
- spec/ext/fixnum_spec.rb
|
119
|
+
- spec/spec_helper.rb
|
120
|
+
homepage: https://github.com/thil/currency_exchange
|
121
|
+
licenses: []
|
122
|
+
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
version: "0"
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
hash: 3
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
requirements: []
|
147
|
+
|
148
|
+
rubyforge_project: currency_exchange
|
149
|
+
rubygems_version: 1.8.9
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: A basic library to retrieve and convert currency
|
153
|
+
test_files:
|
154
|
+
- spec/data/currencies_spec.rb
|
155
|
+
- spec/exchangers/open_exchange_spec.rb
|
156
|
+
- spec/ext/fixnum_spec.rb
|
157
|
+
- spec/spec_helper.rb
|