diff --git a/minitest/navy.rb b/minitest/navy.rb index c672e0a..cc73f2e 100644 --- a/minitest/navy.rb +++ b/minitest/navy.rb @@ -1,4 +1,6 @@ class Admiral + attr_reader :battleship + def initialize(battleship) @battleship = battleship end @@ -10,12 +12,51 @@ def fire_upon_target end class Battleship - attr_reader :ammunition - def initialize - @ammunition = 100 + attr_reader :ammunition, :armory, :fate + def initialize(armory, fate) + @ammunition = 10 + @armory = armory + @fate = fate end def fire! @ammunition = @ammunition - 1 + reload! if @ammunition == 0 + fate.report + end + + def reload! + @ammunition += @armory.request_ammunition(10) + end +end + +class Armory + attr_reader :ammunition_reserves + + def initialize(reserves) + @ammunition_reserves = reserves + end + + def request_ammunition(amount) + if amount <= @ammunition_reserves + @ammunition_reserves = @ammunition_reserves - amount + amount + else + available = @ammunition_reserves + @ammunition_reserves = 0 + available + end + end + +end + +class Fate + + def initialize(randomizer=Random) + @randomizer = randomizer + end + + def report + @randomizer.rand(11).even? end end diff --git a/minitest/navy_test.rb b/minitest/navy_test.rb index de35ec0..123488d 100644 --- a/minitest/navy_test.rb +++ b/minitest/navy_test.rb @@ -9,6 +9,10 @@ def setup @admiral = Admiral.new(@battleship) end + def test_the_admiral_has_a_battleship + assert_equal @battleship.object_id, @admiral.battleship.object_id + end + def test_can_tell_the_battleship_to_fire @battleship.expect :fire!, nil @admiral.fire_upon_target @@ -17,19 +21,93 @@ def test_can_tell_the_battleship_to_fire end class TestBattleship< MiniTest::Unit::TestCase + def setup + @armory = MiniTest::Mock.new + @fate = MiniTest::Mock.new + @battleship = Battleship.new(@armory, @fate) + @starting_ammunition = @battleship.ammunition + end + + def test_starts_with_ten_rounds_of_ammunition + assert_equal 10, @starting_ammunition + end + def test_will_decrease_ammunition_when_firing - battleship = Battleship.new - starting_ammunition = battleship.ammunition - battleship.fire! - assert_equal (starting_ammunition - 1), battleship.ammunition + @fate.expect(:report, true) + @battleship.fire! + assert_equal @starting_ammunition - 1, @battleship.ammunition end end describe Battleship do + + let(:armory) { MiniTest::Mock.new } + let(:fate) { MiniTest::Mock.new } + let(:ship) { Battleship.new(armory, fate) } + it "should decrease ammo" do - battleship = Battleship.new - starting_ammunition = battleship.ammunition - battleship.fire! - battleship.ammunition.must_equal (starting_ammunition -1) + fate.expect(:report, true) + starting_ammo = ship.ammunition + ship.fire! + ship.ammunition.must_equal(starting_ammo - 1) + end + + it "can request more ammo" do + fate.expect(:report, true) + armory.expect(:request_ammunition, 10, [Integer]) + while ship.ammunition >= 2 + ship.fire! + end + ship.fire! + armory.verify + end + + it "should recieve more ammo" do + fate.expect(:report, true) + armory.expect(:request_ammunition, 10, [Integer]) + starting_ammo = ship.ammunition + ship.reload! + ship.ammunition.must_equal(starting_ammo + 10) + end + + it "should know if there was a hit or miss after firing" do + fate.expect(:report, true) + ship.fire!.must_equal(true) + end + +end + +describe Armory do + + subject { Armory.new(100) } + + it "should have reserve ammunition" do + subject.ammunition_reserves.must_equal(100) + end + + it "should provide ammunition if it has enough" do + subject.request_ammunition(10).must_equal 10 + end + + it "should provide partial ammunition if it doesn't have enough" do + available = subject.ammunition_reserves + subject.request_ammunition(available + 10).must_equal available + end +end + +describe Fate do + + it "should return true if rand is even" do + mock_rand = MiniTest::Mock.new + fate = Fate.new(mock_rand) + mock_rand.expect(:rand, 6, [Integer]) + fate.report.must_equal true + end + + it "should return false if rand is odd" do + mock_rand = MiniTest::Mock.new + fate = Fate.new(mock_rand) + mock_rand.expect(:rand, 5, [Integer]) + fate.report.must_equal false end end