From c317e6f852ceace83dac3faf2a4ad45cb3aed848 Mon Sep 17 00:00:00 2001 From: titan2gman Date: Thu, 25 May 2023 21:08:56 +0900 Subject: [PATCH] Add models and update spec --- .ruby-version | 2 +- Gemfile.lock | 27 ++-- award.rb | 1 - models.rb | 85 ++++++++++++ update_quality.rb | 49 ------- update_quality_spec.rb | 303 ++++++++++++++++++++--------------------- 6 files changed, 253 insertions(+), 214 deletions(-) delete mode 100644 award.rb create mode 100644 models.rb delete mode 100644 update_quality.rb diff --git a/.ruby-version b/.ruby-version index 37c2961..6ebad14 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.2 +3.1.2 \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 64449d5..0c81113 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,23 +1,28 @@ GEM remote: https://rubygems.org/ specs: - diff-lcs (1.2.5) + diff-lcs (1.5.0) rake (13.0.6) - rspec (2.14.1) - rspec-core (~> 2.14.0) - rspec-expectations (~> 2.14.0) - rspec-mocks (~> 2.14.0) - rspec-core (2.14.8) - rspec-expectations (2.14.5) - diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.6) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) PLATFORMS - ruby + x86_64-linux DEPENDENCIES rake rspec BUNDLED WITH - 2.3.16 + 2.3.23 diff --git a/award.rb b/award.rb deleted file mode 100644 index 5208232..0000000 --- a/award.rb +++ /dev/null @@ -1 +0,0 @@ -Award = Struct.new(:name, :expires_in, :quality) diff --git a/models.rb b/models.rb new file mode 100644 index 0000000..b55ca6e --- /dev/null +++ b/models.rb @@ -0,0 +1,85 @@ +module Award + attr_reader :expires_in, :quality + + def initialize(expires_in, quality) + validate_input(expires_in, quality) + @expires_in = expires_in + @quality = quality + end + + def is_distinction_plus? + self.class.name == "BlueDistinctionPlusAward" + end + + def update_quality + unless is_distinction_plus? + update_expiry + super + normalize_quality + end + end + + def update_expiry + @expires_in -= 1 + end + + def expired? + @expires_in <= 0 + end + + def validate_input(expires_in, quality) + raise "Invalid expiry" unless expires_in.is_a?(Integer) + raise "Invalid quality" unless quality.is_a?(Integer) && ( + is_distinction_plus? ? quality == 80 : (0..50).include?(quality) + ) + end + + def normalize_quality + @quality = 50 if @quality > 50 + @quality = 0 if @quality < 0 + end +end + +class BaseAward + prepend Award + + def update_quality + @quality -= (expired? ? 2: 1) + end +end + +class BlueFirstAward + prepend Award + + def update_quality + @quality += (expired? ? 2 : 1) + end +end + +class BlueDistinctionPlusAward + prepend Award +end + +class BlueCompareAward + prepend Award + + def update_quality + if @expires_in < 0 + @quality = 0 + elsif @expires_in <= 4 + @quality += 3 + elsif @expires_in <= 9 + @quality += 2 + else + @quality += 1 + end + end +end + +class BlueStarAward + prepend Award + + def update_quality + @quality -= (expired? ? 4: 2) + end +end diff --git a/update_quality.rb b/update_quality.rb deleted file mode 100644 index bd1f10f..0000000 --- a/update_quality.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'award' - -def update_quality(awards) - awards.each do |award| - if award.name != 'Blue First' && award.name != 'Blue Compare' - if award.quality > 0 - if award.name != 'Blue Distinction Plus' - award.quality -= 1 - end - end - else - if award.quality < 50 - award.quality += 1 - if award.name == 'Blue Compare' - if award.expires_in < 11 - if award.quality < 50 - award.quality += 1 - end - end - if award.expires_in < 6 - if award.quality < 50 - award.quality += 1 - end - end - end - end - end - if award.name != 'Blue Distinction Plus' - award.expires_in -= 1 - end - if award.expires_in < 0 - if award.name != 'Blue First' - if award.name != 'Blue Compare' - if award.quality > 0 - if award.name != 'Blue Distinction Plus' - award.quality -= 1 - end - end - else - award.quality = award.quality - award.quality - end - else - if award.quality < 50 - award.quality += 1 - end - end - end - end -end diff --git a/update_quality_spec.rb b/update_quality_spec.rb index 973940d..2fae17d 100644 --- a/update_quality_spec.rb +++ b/update_quality_spec.rb @@ -1,214 +1,213 @@ require 'rspec' -require 'update_quality' +require 'models' describe '#update_quality' do - context 'Given a single award' do let(:initial_expires_in) { 5 } let(:initial_quality) { 10 } - let(:award) { Award.new(name, initial_expires_in, initial_quality) } - context 'when quality is updated' do + context 'given a normal award' do + let(:award) { BaseAward.new(initial_expires_in, initial_quality) } + before do - update_quality([award]) + award.update_quality + # Verify that this is always true in the current context + expect(award.expires_in).to eq(initial_expires_in-1) end - context 'given a normal award' do - let(:name) { 'NORMAL ITEM' } + context 'before expiration date' do + specify { expect(award.quality).to eq(initial_quality-1) } + end - before do - # Verify that this is always true in the current context - expect(award.expires_in).to eq(initial_expires_in-1) - end + context 'on expiration date' do + let(:initial_expires_in) { 0 } + specify { expect(award.quality).to eq(initial_quality-2) } + end - context 'before expiration date' do - specify { expect(award.quality).to eq(initial_quality-1) } - end + context 'after expiration date' do + let(:initial_expires_in) { -10 } + specify { expect(award.quality).to eq(initial_quality-2) } + end - context 'on expiration date' do - let(:initial_expires_in) { 0 } - specify { expect(award.quality).to eq(initial_quality-2) } - end + context 'of zero quality' do + let(:initial_quality) { 0 } + specify { expect(award.quality).to eq(0) } + end + end - context 'after expiration date' do - let(:initial_expires_in) { -10 } - specify { expect(award.quality).to eq(initial_quality-2) } - end + context 'given Blue First' do + let(:award) { BlueFirstAward.new(initial_expires_in, initial_quality) } - context 'of zero quality' do - let(:initial_quality) { 0 } - specify { expect(award.quality).to eq(0) } - end + before do + award.update_quality + # Verify that this is always true in the current context + expect(award.expires_in).to eq(initial_expires_in-1) end - context 'given Blue First' do - let(:name) { 'Blue First' } + context 'before expiration date' do + specify { expect(award.quality).to eq(initial_quality+1) } - before do - # Verify that this is always true in the current context - award.expires_in.should == initial_expires_in-1 + context 'with max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'before expiration date' do - specify { expect(award.quality).to eq(initial_quality+1) } + context 'on expiration date' do + let(:initial_expires_in) { 0 } + specify { expect(award.quality).to eq(initial_quality+2) } - context 'with max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'near max quality' do + let(:initial_quality) { 49 } + specify { expect(award.quality).to eq(50) } end - context 'on expiration date' do - let(:initial_expires_in) { 0 } - specify { expect(award.quality).to eq(initial_quality+2) } - - context 'near max quality' do - let(:initial_quality) { 49 } - specify { expect(award.quality).to eq(50) } - end - - context 'with max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'with max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'after expiration date' do - let(:initial_expires_in) { -10 } - specify { expect(award.quality).to eq(initial_quality+2) } + context 'after expiration date' do + let(:initial_expires_in) { -10 } + specify { expect(award.quality).to eq(initial_quality+2) } - context 'with max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'with max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end end + end - context 'given Blue Distinction Plus' do - let(:initial_quality) { 80 } - let(:name) { 'Blue Distinction Plus' } + context 'given Blue Distinction Plus' do + let(:initial_quality) { 80 } + let(:award) { BlueDistinctionPlusAward.new(initial_expires_in, initial_quality) } - before do - # Verify that this is always true in the current context - award.expires_in.should == initial_expires_in - end + before do + # Verify that this is always true in the current context + expect(award.expires_in).to eq(initial_expires_in) + end - context 'before expiration date' do - specify { expect(award.quality).to eq(initial_quality) } - end + context 'before expiration date' do + specify { expect(award.quality).to eq(initial_quality) } + end - context 'on expiration date' do - let(:initial_expires_in) { 0 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'on expiration date' do + let(:initial_expires_in) { 0 } + specify { expect(award.quality).to eq(initial_quality) } + end - context 'after expiration date' do - let(:initial_expires_in) { -10 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'after expiration date' do + let(:initial_expires_in) { -10 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'given Blue Compare' do - let(:name) { 'Blue Compare' } + context 'given Blue Compare' do + let(:award) { BlueCompareAward.new(initial_expires_in, initial_quality) } - before do - # Verify that this is always true in the current context - award.expires_in.should == initial_expires_in-1 - end + before do + award.update_quality + # Verify that this is always true in the current context + expect(award.expires_in).to eq(initial_expires_in-1) + end - context 'long before expiration date' do - let(:initial_expires_in) { 11 } - specify { expect(award.quality).to eq(initial_quality+1) } + context 'long before expiration date' do + let(:initial_expires_in) { 11 } + specify { expect(award.quality).to eq(initial_quality+1) } - context 'at max quality' do - let(:initial_quality) { 50 } - end + context 'at max quality' do + let(:initial_quality) { 50 } end + end - context 'medium close to expiration date (upper bound)' do - let(:initial_expires_in) { 10 } - specify { expect(award.quality).to eq(initial_quality+2) } + context 'medium close to expiration date (upper bound)' do + let(:initial_expires_in) { 10 } + specify { expect(award.quality).to eq(initial_quality+2) } - context 'at max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'at max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'medium close to expiration date (lower bound)' do - let(:initial_expires_in) { 6 } - specify { expect(award.quality).to eq(initial_quality+2) } + context 'medium close to expiration date (lower bound)' do + let(:initial_expires_in) { 6 } + specify { expect(award.quality).to eq(initial_quality+2) } - context 'at max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'at max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'very close to expiration date (upper bound)' do - let(:initial_expires_in) { 5 } - specify { expect(award.quality).to eq(initial_quality+3) } + context 'very close to expiration date (upper bound)' do + let(:initial_expires_in) { 5 } + specify { expect(award.quality).to eq(initial_quality+3) } - context 'at max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'at max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'very close to expiration date (lower bound)' do - let(:initial_expires_in) { 1 } - specify { expect(award.quality).to eq(initial_quality+3) } + context 'very close to expiration date (lower bound)' do + let(:initial_expires_in) { 1 } + specify { expect(award.quality).to eq(initial_quality+3) } - context 'at max quality' do - let(:initial_quality) { 50 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'at max quality' do + let(:initial_quality) { 50 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'on expiration date' do - let(:initial_expires_in) { 0 } - specify { expect(award.quality).to eq(0) } - end + context 'on expiration date' do + let(:initial_expires_in) { 0 } + specify { expect(award.quality).to eq(0) } + end - context 'after expiration date' do - let(:initial_expires_in) { -10 } - specify { expect(award.quality).to eq(0) } - end + context 'after expiration date' do + let(:initial_expires_in) { -10 } + specify { expect(award.quality).to eq(0) } end + end - context 'given a Blue Star award' do - before { pending } - let(:name) { 'Blue Star' } - before { award.expires_in.should == initial_expires_in-1 } + context 'given a Blue Star award' do + let(:award) { BlueStarAward.new(initial_expires_in, initial_quality) } - context 'before the expiration date' do - let(:initial_expires_in) { 5 } - specify { expect(award.quality).to eq(initial_quality-2) } + before do + award.update_quality + # Verify that this is always true in the current context + expect(award.expires_in).to eq(initial_expires_in-1) + end - context 'at zero quality' do - let(:initial_quality) { 0 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'before the expiration date' do + let(:initial_expires_in) { 5 } + specify { expect(award.quality).to eq(initial_quality-2) } + + context 'at zero quality' do + let(:initial_quality) { 0 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'on expiration date' do - let(:initial_expires_in) { 0 } - specify { expect(award.quality).to eq(initial_quality-4) } + context 'on expiration date' do + let(:initial_expires_in) { 0 } + specify { expect(award.quality).to eq(initial_quality-4) } - context 'at zero quality' do - let(:initial_quality) { 0 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'at zero quality' do + let(:initial_quality) { 0 } + specify { expect(award.quality).to eq(initial_quality) } end + end - context 'after expiration date' do - let(:initial_expires_in) { -10 } - specify { expect(award.quality).to eq(initial_quality-4) } + context 'after expiration date' do + let(:initial_expires_in) { -10 } + specify { expect(award.quality).to eq(initial_quality-4) } - context 'at zero quality' do - let(:initial_quality) { 0 } - specify { expect(award.quality).to eq(initial_quality) } - end + context 'at zero quality' do + let(:initial_quality) { 0 } + specify { expect(award.quality).to eq(initial_quality) } end end end @@ -217,14 +216,14 @@ context 'Given several award' do let(:awards) { [ - Award.new('NORMAL ITEM', 5, 10), - Award.new('Blue First', 3, 10), + BaseAward.new(5, 10), + BlueFirstAward.new(3, 10), ] } context 'when quality is updated' do before do - update_quality(awards) + awards.each(&:update_quality) end specify { expect(awards[0].quality).to eq(9) } @@ -234,4 +233,4 @@ specify { expect(awards[1].expires_in).to eq(2) } end end -end +end \ No newline at end of file