mirror of
https://github.com/hakanensari/frankfurter.git
synced 2024-11-24 20:15:15 +01:00
Refactor snapshot
This commit is contained in:
parent
cfea8e71ad
commit
631d42207b
3
Gemfile
3
Gemfile
@ -5,7 +5,8 @@ gem 'pg'
|
||||
gem 'sequel'
|
||||
gem 'sinatra-jsonp'
|
||||
gem 'unicorn'
|
||||
gem 'yajl-ruby', require: 'yajl'
|
||||
gem 'virtus'
|
||||
gem 'yajl-ruby'
|
||||
|
||||
group :development do
|
||||
gem 'minitest'
|
||||
|
@ -1,6 +1,7 @@
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
backports (2.6.5)
|
||||
fixer (0.5.0)
|
||||
nokogiri (~> 1.5)
|
||||
kgio (2.7.4)
|
||||
@ -29,6 +30,8 @@ GEM
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
raindrops (~> 0.7)
|
||||
virtus (0.5.2)
|
||||
backports (~> 2.6.1)
|
||||
yajl-ruby (1.1.0)
|
||||
|
||||
PLATFORMS
|
||||
@ -43,4 +46,5 @@ DEPENDENCIES
|
||||
shotgun
|
||||
sinatra-jsonp
|
||||
unicorn
|
||||
virtus
|
||||
yajl-ruby
|
||||
|
20
lib/app.rb
20
lib/app.rb
@ -6,8 +6,10 @@ require 'yajl'
|
||||
set :root, File.expand_path('..', File.dirname(__FILE__))
|
||||
|
||||
helpers do
|
||||
def base
|
||||
params[:base] || Snapshot::DEFAULT_BASE
|
||||
def snapshot
|
||||
Snapshot
|
||||
.new(params)
|
||||
.quote
|
||||
end
|
||||
end
|
||||
|
||||
@ -16,15 +18,13 @@ get '/' do
|
||||
end
|
||||
|
||||
get '/latest' do
|
||||
jsonp Snapshot
|
||||
.last
|
||||
.with_base(base)
|
||||
.to_hash
|
||||
jsonp snapshot
|
||||
end
|
||||
|
||||
get '/:date' do
|
||||
jsonp Snapshot
|
||||
.new(params[:date])
|
||||
.with_base(base)
|
||||
.to_hash
|
||||
jsonp snapshot
|
||||
end
|
||||
|
||||
error do
|
||||
"Something is rotten in the state of Denmark."
|
||||
end
|
||||
|
@ -1,59 +1,49 @@
|
||||
require_relative 'db'
|
||||
require 'virtus'
|
||||
|
||||
class Snapshot
|
||||
DEFAULT_BASE = 'EUR'
|
||||
include Virtus
|
||||
|
||||
def self.last
|
||||
new Currency.last_date
|
||||
end
|
||||
attribute :base, String, default: 'EUR'
|
||||
attribute :date, Date, default: proc { Currency.last_date }
|
||||
|
||||
def initialize(date)
|
||||
@date = date
|
||||
@base = DEFAULT_BASE
|
||||
end
|
||||
|
||||
# Ugly as fuck.
|
||||
def to_hash
|
||||
rebased_rates = rates
|
||||
|
||||
unless @base == DEFAULT_BASE
|
||||
base_rate = rebased_rates
|
||||
.update('EUR' => 1.0)
|
||||
.delete @base
|
||||
|
||||
rebased_rates.each do |iso_code, rate|
|
||||
new_rate = rate / base_rate
|
||||
rebased_rates[iso_code] =
|
||||
case new_rate
|
||||
when new_rate > 100
|
||||
new_rate.round 2
|
||||
when new_rate > 10
|
||||
new_rate.round 3
|
||||
else
|
||||
new_rate.round 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
{
|
||||
base: @base,
|
||||
date: @date,
|
||||
rates: rebased_rates
|
||||
}
|
||||
end
|
||||
|
||||
def with_base(base)
|
||||
@base = base
|
||||
self
|
||||
def quote
|
||||
attributes.merge rates: rebase(rates)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rates
|
||||
Currency
|
||||
.where(date: @date)
|
||||
.reduce({}) { |hsh, currency|
|
||||
hsh.update currency.to_hash
|
||||
}
|
||||
.where(date: date)
|
||||
.reduce({}) do |rates, currency|
|
||||
rates.update currency.to_hash
|
||||
end
|
||||
end
|
||||
|
||||
# Ugly as fuck.
|
||||
def rebase(rates)
|
||||
if base.upcase! != 'EUR'
|
||||
denominator = rates
|
||||
.update('EUR' => 1.0)
|
||||
.delete base
|
||||
|
||||
rates.each do |iso_code, rate|
|
||||
rates[iso_code] = round(rate / denominator)
|
||||
end
|
||||
end
|
||||
|
||||
rates
|
||||
end
|
||||
|
||||
def round(rate)
|
||||
case rate
|
||||
when rate > 100
|
||||
rate.round 2
|
||||
when rate > 10
|
||||
rate.round 3
|
||||
else
|
||||
rate.round 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -7,6 +7,7 @@ describe 'the application' do
|
||||
|
||||
let(:app) { Sinatra::Application }
|
||||
let(:json) { Yajl::Parser.new.parse last_response.body }
|
||||
let(:status) { last_response.status }
|
||||
|
||||
it 'returns latest snapshot' do
|
||||
get '/latest'
|
||||
|
@ -1,31 +0,0 @@
|
||||
require_relative 'helper'
|
||||
require 'snapshot'
|
||||
|
||||
describe 'when rebased to a new base' do
|
||||
let(:new_base) { 'USD' }
|
||||
let(:snapshot) { Snapshot.new 'a date' }
|
||||
let(:rates) { { new_base => 1.2781 } }
|
||||
let(:rebased_hash) do
|
||||
snapshot.stub :rates, rates do
|
||||
snapshot
|
||||
.with_base(new_base)
|
||||
.to_hash
|
||||
end
|
||||
end
|
||||
|
||||
it 'resets base' do
|
||||
rebased_hash[:base].must_equal new_base
|
||||
end
|
||||
|
||||
it 'adds former base to rates' do
|
||||
rebased_hash[:rates].keys.must_include Snapshot::DEFAULT_BASE
|
||||
end
|
||||
|
||||
it 'removes new base from rates' do
|
||||
rebased_hash[:rates].keys.wont_include new_base
|
||||
end
|
||||
|
||||
it 'rebases rates' do
|
||||
rebased_hash[:rates][Snapshot::DEFAULT_BASE].must_equal 0.7824
|
||||
end
|
||||
end
|
44
spec/snapshot_spec.rb
Normal file
44
spec/snapshot_spec.rb
Normal file
@ -0,0 +1,44 @@
|
||||
require_relative 'helper'
|
||||
require 'snapshot'
|
||||
|
||||
describe Snapshot do
|
||||
let(:snapshot) { Snapshot.new }
|
||||
|
||||
def stub_rates(rates = {})
|
||||
snapshot.stub :rates, rates do
|
||||
yield snapshot.quote[:rates]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'by default' do
|
||||
it 'quotes rates against the euro' do
|
||||
stub_rates 'USD' => 1.25 do |quotes|
|
||||
quotes['USD'].must_equal 1.25
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not quote the euro' do
|
||||
stub_rates do |quotes|
|
||||
quotes.keys.wont_include 'EUR'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when base is set to a non-euro currency' do
|
||||
before do
|
||||
snapshot.base = 'USD'
|
||||
end
|
||||
|
||||
it 'quotes rates against that currency' do
|
||||
stub_rates 'USD' => 1.25 do |quotes|
|
||||
quotes['EUR'].must_equal 0.8
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not quote the base currency' do
|
||||
stub_rates 'USD' => 1.25 do |quotes|
|
||||
quotes.keys.wont_include 'USD'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user