require_relative '../lib/crypto_arbitrer.rb' require 'webmock/rspec' require 'csv' RSpec.configure do |config| config.include CryptoArbitrer::SpecHelper end describe CryptoArbitrer::Base do describe 'when matching corpus of conversion rates' do before :each do mock_crypto_arbitrer_requests! end CSV.read(File.expand_path('../conversions.csv', __FILE__), 'r').each do |from, to, buy, sell| it "converts from #{from} to #{to}" do rate = subject.fetch(from, to) rate['buy'].should == buy.to_f rate['sell'].should == sell.to_f end end # As a sanity check, we make sure all conversions advertised as supported at least exists. # You should always increase the conversions.csv corpus when adding a new currency though. CryptoArbitrer::Base.supported_conversions.each do |from, to| it "Conversion from #{from} to #{to} exists" do subject.send("fetch_#{from}_#{to}").tap do |rate| # When adding a new currency, you may want to print out the rates returned by the engine # to check them manually and then add them to the corpus #puts "#{from},#{to},#{rate['buy']},#{rate['sell']}" rate['buy'].should_not be_nil rate['sell'].should_not be_nil end end end it 'supports conversions from and to the same currency' do subject.class.supported_currencies.each do |c| subject.fetch(c,c).should == {'buy' => 1, 'sell' => 1} end end end it 'hits dolarblue for usd to ars rate' do stub = stub_crypto_arbitrer_get("http://www.eldolarblue.net/getDolarBlue.php?as=json", 'dolarblue.json') subject.fetch_usd_ars stub.should have_been_requested end it 'hits mt.gox for the btc to usd rate' do stub = stub_crypto_arbitrer_get('http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast', 'mtgox.json') subject.fetch_btc_usd stub.should have_been_requested end it 'hits dolarparalelo for venezuelan bolivar' do stub = stub_crypto_arbitrer_get('http://www.dolarparalelo.org/', 'dolarparalelo.html') subject.fetch_usd_vef stub.should have_been_requested end it 'hits mt.gox and dolarblue for the btc to ars rate' do stub_ars = stub_crypto_arbitrer_get("http://www.eldolarblue.net/getDolarBlue.php?as=json", 'dolarblue.json') stub_btc = stub_crypto_arbitrer_get('http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast', 'mtgox.json') subject.fetch_btc_ars stub_ars.should have_been_requested stub_btc.should have_been_requested end %w(ltc nmc nvc trc ppc ftc cnc).each do |currency| it "hits btc-e for the #{currency} to btc rate" do stub = stub_crypto_arbitrer_get("https://btc-e.com/exchange/#{currency}_btc", "btce_#{currency}_btc.html") subject.fetch(currency, 'btc') subject.fetch('btc', currency) stub.should have_been_requested.twice end end %w(uyu brl clp sgd eur).each do |currency| it "hits rate-exchange for the #{currency} to usd rate" do stub = stub_crypto_arbitrer_get("http://rate-exchange.appspot.com/currency?from=usd&to=#{currency}", "rate_exchange_usd_#{currency}.json") subject.fetch('usd', currency) subject.fetch(currency, 'usd') stub.should have_been_requested.twice end end describe 'when caching remote calls' do it 'does not cache anything by default' do stub = stub_crypto_arbitrer_get("http://www.eldolarblue.net/getDolarBlue.php?as=json", 'dolarblue.json') 2.times{ subject.fetch('usd', 'ars') } stub.should have_been_requested.twice end it 'caches when a cache_backend has been set, stops caching afterwards' do cache = {} subject.class.cache_backend = lambda {|from, to, block| cache[[from,to]] ||= block.call } stub = stub_crypto_arbitrer_get('http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast', 'mtgox.json') subject.fetch('btc', 'usd') cache[['btc','usd']].should be_a(Hash) subject.fetch('btc', 'usd') stub.should have_been_requested.once subject.class.cache_backend = nil subject.fetch('btc', 'usd') stub.should have_been_requested.twice end it 'does not cache for low level calls' do cache = {} subject.class.cache_backend = lambda {|from, to, block| cache[key] ||= block.call } stub = stub_crypto_arbitrer_get('http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast', 'mtgox.json') subject.fetch_btc_usd subject.fetch_btc_usd stub.should have_been_requested.twice end it 'does not cache when using a force argument' do cache = {} subject.class.cache_backend = lambda {|from, to, block| cache[key] ||= block.call } stub = stub_crypto_arbitrer_get('http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast', 'mtgox.json') subject.fetch('btc', 'usd', true) subject.fetch('btc', 'usd', true) stub.should have_been_requested.twice end end describe "Service is either down or changed their API at:", slow: true do before(:all){ WebMock.allow_net_connect! } after(:all){ WebMock.disable_net_connect! } def check_service(method) %w(buy sell).each do |price| price = subject.send(method)[price] price.should be_a Float price.should >= 0 end end it 'eldolarblue' do check_service(:fetch_usd_ars) end it 'mtgox' do check_service(:fetch_btc_usd) end %w(ltc_btc nmc_btc nvc_btc trc_btc ppc_btc ftc_btc cnc_btc).each do |exchange| it "btce #{exchange}" do check_service("fetch_#{exchange}") end end it 'rate-exchange' do check_service('fetch_usd_sgd') end it 'dolarparalelo' do check_service('fetch_usd_vef') end end end