Skip to content

Instantly share code, notes, and snippets.

@fabioperrella
Created September 27, 2021 08:05
Show Gist options
  • Save fabioperrella/17e7df3146989b2d0c46777bf1f35310 to your computer and use it in GitHub Desktop.
Save fabioperrella/17e7df3146989b2d0c46777bf1f35310 to your computer and use it in GitHub Desktop.
# To run:
# gem install rspec
# rspec mb.rb
class Pocket
attr_reader :white, :red, :blue, :black, :green
InvalidValueForColor = Class.new(StandardError)
def initialize(white: 0, red: 0, blue: 0, black: 0, green: 0)
raise InvalidValueForColor if white < 0 || red < 0 || blue < 0 || black < 0 || green < 0
@white = white
@red = red
@blue = blue
@black = black
@green = green
end
def to_h
{
white: white,
red: red,
blue: blue,
black: black,
green: green
}
end
end
class CardPrice
attr_reader :white, :red, :blue, :black, :green
def initialize(white: 0, red: 0, blue: 0, black: 0, green: 0)
@white = white
@red = red
@blue = blue
@black = black
@green = green
end
end
class Card
attr_reader :price
def initialize(price:)
@price = price
end
end
module CardTransaction
extend self
NotEnoughCredits = Class.new(StandardError)
def can_buy?(pocket:, card:)
pocket.white >= card.price.white &&
pocket.red >= card.price.red &&
pocket.blue >= card.price.blue &&
pocket.black >= card.price.black &&
pocket.green >= card.price.green
end
def buy(pocket:, card:)
raise NotEnoughCredits unless can_buy?(pocket: pocket, card: card)
new_pocket = Pocket.new(
white: pocket.white - card.price.white,
red: pocket.red - card.price.red,
blue: pocket.blue - card.price.blue,
black: pocket.black - card.price.black,
green: pocket.green - card.price.green
)
end
end
## ---------------------- tests -------------------------
require 'rspec'
describe CardTransaction do
describe '.can_buy?' do
it 'returns true when the pocket has enough plastic disks' do
pocket = Pocket.new(red: 1, white: 2)
card_price = CardPrice.new(red: 1, white: 1)
card = Card.new(price: card_price)
result = CardTransaction.can_buy?(pocket: pocket, card: card)
expect(result).to eq(true)
end
it 'returns false when the pocket does not have enough plastic disks' do
pocket = Pocket.new(red: 1, white: 2)
card_price = CardPrice.new(red: 1, white: 1, blue: 1)
card = Card.new(price: card_price)
result = CardTransaction.can_buy?(pocket: pocket, card: card)
expect(result).to eq(false)
end
it 'returns true when the pocket has the exact amount' do
pocket = Pocket.new(red: 1, white: 2)
card_price = CardPrice.new(red: 1, white: 2)
card = Card.new(price: card_price)
result = CardTransaction.can_buy?(pocket: pocket, card: card)
expect(result).to eq(true)
end
end
describe '.buy' do
it 'raises an error when the credit is not enough' do
pocket = Pocket.new(red: 1, white: 2)
card_price = CardPrice.new(red: 2, white: 1)
card = Card.new(price: card_price)
expect { CardTransaction.buy(pocket: pocket, card: card) }
.to raise_error(CardTransaction::NotEnoughCredits)
end
it 'returns a pocket with the updated quantity of plastic disks' do
pocket = Pocket.new(red: 1, white: 2)
card_price = CardPrice.new(red: 1, white: 1)
card = Card.new(price: card_price)
new_pocket = CardTransaction.buy(pocket: pocket, card: card)
expect(new_pocket.to_h).to eq(
white: 1,
red: 0,
blue: 0,
black: 0,
green: 0
)
end
end
end
describe Pocket do
it 'does not allow negative values for plastic disk colors' do
expect { Pocket.new(white: -1) }
.to raise_error(Pocket::InvalidValueForColor)
expect { Pocket.new(red: -1) }
.to raise_error(Pocket::InvalidValueForColor)
expect { Pocket.new(blue: -1) }
.to raise_error(Pocket::InvalidValueForColor)
expect { Pocket.new(black: -1) }
.to raise_error(Pocket::InvalidValueForColor)
expect { Pocket.new(green: -1) }
.to raise_error(Pocket::InvalidValueForColor)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment