<file_sep>require_relative 'item_basic'

class NormalItem

  include ItemBasic

  def update_quality
    in_date? ? lost_quality = 1 : lost_quality = 2
    lost_quality = @quality if @quality - lost_quality < 0
    @quality -= lost_quality
  end

  def update_sell_in
    @sell_in -= 1
  end

  private

  def in_date?
    @sell_in >= 0
  end

end
<file_sep>require_relative 'item_basic'

class GrowItem

  include ItemBasic

  def update_quality
    @quality - lost_quality > 50 ? quality = @quality -50 : quality = lost_quality
    @quality -= quality
  end

  def update_sell_in
    @sell_in -= 1
  end

  private

  def lost_quality
    sell_in < 0 ? -2 : -1
  end

end
<file_sep>require 'normal_item'
require 'item_basic'

describe NormalItem do

  let(:subject) {NormalItem.new("A normal item",10,20)}

  it_behaves_like ItemBasic

  it 'decreases quality by 1 when in date' do
    expect{subject.update_quality}.to change{subject.quality}.by(-1)
  end

  it 'decreases quality by 2 when not in date' do
    subject.sell_in = -1
    expect{subject.update_quality}.to change{subject.quality}.by(-2)
  end

  it 'can not have a negative quality' do
    subject.quality = 0
    expect{subject.update_quality}.to change{subject.quality}.by(0)
  end

  it 'changes sell_in by -1' do
    expect{subject.update_sell_in}.to change{subject.sell_in}.by(-1)
  end
end
<file_sep>require 'legendary'
require 'item_basic'

describe Legendary do

  let(:subject) {Legendary.new("A legendary item",0,80)}

  it_behaves_like ItemBasic

  it 'never changes quality' do
    expect{subject.update_quality}.to change{subject.quality}.by(0)
  end

  it 'changes sell_in by 0' do
    expect{subject.update_sell_in}.to change{subject.sell_in}.by(0)
  end
end
<file_sep>require 'unnormal_item'
require 'item_basic'

describe GrowItem do

  let(:subject) {GrowItem.new("An appriciating item",40,20)}

  it_behaves_like ItemBasic

  it 'increases in quality by 1 when in date' do
    subject.sell_in = 0
    expect{subject.update_quality}.to change{subject.quality}.by(1)
  end

  it 'increases in quality by 2 when not in date' do
    subject.sell_in = -1
    expect{subject.update_quality}.to change{subject.quality}.by(2)
  end

  it 'never raises quality to above 50' do
    subject.quality = 50
    expect{subject.update_quality}.to change{subject.quality}.by(0)
  end

  it 'raises quality from 49 to 50' do
    subject.quality = 49
    subject.sell_in = -1
    expect{subject.update_quality}.to change{subject.quality}.by(1)
  end

  it 'changes sell_in by -1' do
    expect{subject.update_sell_in}.to change{subject.sell_in}.by(-1)
  end

end
<file_sep>require 'item_basic'

shared_examples_for ItemBasic do

  it { is_expected.to respond_to :name }

  it { is_expected.to respond_to :quality }

  it { is_expected.to respond_to :sell_in }

end
<file_sep>require_relative 'item_basic'

class Ticket

  include ItemBasic

  def update_quality
    @quality - lost_quality > 50 ? quality = @quality - 50 : quality = lost_quality
    @quality -= quality
  end

  def update_sell_in
    @sell_in -= 1
  end

  private

  def in_10_days
    @sell_in <= 10
  end

  def in_5_days
    @sell_in <= 5
  end

  def lost_quality
    in_10_days ? lost_quality = -2 : lost_quality = -1
    in_5_days ? lost_quality = -3 : 0
    sell_in < 0 ? lost_quality = @quality : lost_quality
  end

end
<file_sep>require_relative 'item_basic'

class Legendary

  include ItemBasic

  def update_quality
    @quality
  end

  def update_sell_in
    @sell_in
  end

end
<file_sep>require 'gilded_rose'
require 'item'

describe GildedRose do

  let(:item) { (double :item, update_quality: true, update_sell_in: -1) }
  let(:subject) {GildedRose.new([item])}

  it 'calls update_quality on the items' do
    expect(item).to receive(:update_quality)
    subject.update_quality
  end

  it 'calls update_sell_in on the items' do
    expect(item).to receive(:update_sell_in)
    subject.update_quality
  end

end
<file_sep>require 'ticket'
require 'item_basic'

describe Ticket do

  let(:subject) {Ticket.new("A ticket",10,20)}

  it_behaves_like ItemBasic

  it 'increases quality by 1 when more than 10 days till event' do
    subject.sell_in = 11
    expect{subject.update_quality}.to change{subject.quality}.by(1)
  end

  it 'increases quality by 2 when less than 10 days till event' do
    subject.sell_in = 10
    expect{subject.update_quality}.to change{subject.quality}.by(2)
  end

  it 'increases quality by 3 when less than 5 days till event' do
    subject.sell_in = 5
    expect{subject.update_quality}.to change{subject.quality}.by(3)
  end

  it 'sets quality to 0 after event' do
    subject.quality = 20
    subject.sell_in = -1
    expect(subject.update_quality).to eq 0
  end

  it 'does not let quality exceed 50' do
    subject.quality = 50
    expect{subject.update_quality}.to change{subject.quality}.by(0)
  end

  it 'changes sell_in by -1' do
    expect{subject.update_sell_in}.to change{subject.sell_in}.by(-1)
  end

end
<file_sep>require 'normal_item'

class GildedRose

  attr_reader :items

  def initialize(items)
    @items = items
  end

  def update_quality
    @items.each do |item|
      item.update_quality
      item.update_sell_in
    end
  end
end
