Convert Snapshot into value object

This commit is contained in:
Hakan Ensari 2015-08-30 11:54:13 +01:00
parent d4b98eef49
commit 1c128eb84c
4 changed files with 31 additions and 30 deletions

View File

@ -2,7 +2,7 @@ require 'sinatra'
require 'sinatra/cross_origin'
require 'sinatra/jsonp'
require 'yajl'
require 'snapshot'
require 'quote'
configure do
enable :cross_origin
@ -17,8 +17,8 @@ configure :production do
end
helpers do
def snapshot
quotes = Snapshot.new(params).quote
def quote
quotes = Quote.new(params).to_h
symbols = params.delete('symbols') || params.delete('currencies')
if symbols
@ -45,12 +45,12 @@ get '/' do
end
get '/latest' do
jsonp snapshot
jsonp quote
end
get(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/) do
process_date
jsonp snapshot
jsonp quote
end
not_found do

View File

@ -1,26 +1,29 @@
require 'virtus'
require 'currency'
# Quotes exchange rates on a specific date
class Snapshot
include Virtus.model
class Quote
include Virtus.value_object
attribute :base, String, default: 'EUR'
attribute :date, Date, default: Currency.current_date
DEFAULT_BASE = 'EUR'
def quote
self.date =
if date
last_date = Currency.current_date_before(date)
fail ArgumentError, 'Date too old' unless last_date
last_date
end
values do
attribute :base, String, default: DEFAULT_BASE
attribute :date, Date, default: Currency.current_date
end
def to_h
attributes.merge(rates: rebase(rates))
end
private
def date=(date)
current_date = Currency.current_date_before(date)
fail ArgumentError, 'Date too old' unless current_date
super current_date
end
def rates
Currency.where(date: date).reduce({}) do |rates, currency|
rates.update(currency.to_hash)
@ -28,8 +31,8 @@ class Snapshot
end
def rebase(rates)
if base.upcase! != 'EUR'
denominator = rates.update('EUR' => 1.0).delete(base)
if base.upcase! != DEFAULT_BASE
denominator = rates.update(DEFAULT_BASE => 1.0).delete(base)
fail ArgumentError, 'Invalid base' unless denominator
rates.each do |iso_code, rate|
rates[iso_code] = round(rate / denominator)

View File

@ -14,7 +14,7 @@ describe 'the API' do
last_response.must_be :ok?
end
it 'returns latest snapshot' do
it 'returns latest quotes' do
get '/latest'
last_response.must_be :ok?
end
@ -29,7 +29,7 @@ describe 'the API' do
json['rates'].keys.must_equal %w(USD)
end
it 'returns historical data' do
it 'returns historical quotes' do
get '/2012-11-20'
json['rates'].wont_be :empty?
json['date'].must_equal '2012-11-20'

View File

@ -1,16 +1,16 @@
require_relative 'helper'
require 'snapshot'
describe Snapshot do
let(:snapshot) { Snapshot.new }
require 'quote'
describe Quote do
def stub_rates(rates = {})
snapshot.stub :rates, rates do
yield snapshot.quote[:rates]
quote.stub :rates, rates do
yield quote.to_h[:rates]
end
end
describe 'by default' do
let(:quote) { Quote.new }
it 'quotes rates against the euro' do
stub_rates 'USD' => 1.25 do |quotes|
quotes['USD'].must_equal 1.25
@ -25,9 +25,7 @@ describe Snapshot do
end
describe 'when base is set to a non-euro currency' do
before do
snapshot.base = 'USD'
end
let(:quote) { Quote.new(base: 'USD') }
it 'quotes rates against that currency' do
stub_rates 'USD' => 1.25 do |quotes|