diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..45c00a8 --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--color +--require ./spec/spec_helper.rb +--format doc diff --git a/Gemfile.lock b/Gemfile.lock index 90f2f48..6025109 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,4 +1,5 @@ GEM + remote: https://rubygems.org/ specs: diff-lcs (1.2.5) rspec (3.1.0) @@ -19,3 +20,6 @@ PLATFORMS DEPENDENCIES rspec + +BUNDLED WITH + 1.16.1 diff --git a/lib/tree.rb b/lib/tree.rb index 6c54019..6934634 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,38 +1,69 @@ class NoApplesError < StandardError; end +class DeadTreeError < StandardError; end -class AppleTree - attr_#fill_in :height, :age, :apples, :alive +class Tree + attr_accessor :height, :age, :apples, :alive - def initialize + def initialize(height: 0, age: 0, apples: [], alive: true) + @height = height + @age = age + @apples = apples + @alive = alive end def age! + raise DeadTreeError, "This tree is dead" if self.dead? + @age += 1 + @height += 1 if @height < 25 + add_apples if @age > 5 + kill! if @age > 200 end def add_apples + raise DeadTreeError, "This tree is dead" if self.dead? + rand(50..100).times { @apples << Apple.new(color: "red", diameter: rand(2..4)) } end def any_apples? + @apples.count > 0 end def pick_an_apple! + raise DeadTreeError, "This tree is dead" if self.dead? raise NoApplesError, "This tree has no apples" unless self.any_apples? + @apples.shift end def dead? + !@alive + end + + def kill! + @alive = false + @apples = [] end end class Fruit - def initialize - has_seeds = true + attr_reader :has_seeds + + def initialize(has_seeds: true) + @has_seeds = has_seeds + end + + def has_seeds? + @has_seeds end end -class Apple < - attr_reader #what should go here +class Apple < Fruit + attr_reader :color, :diameter + + def initialize(color: "red", diameter: 3) + super() - def initialize(color, diameter) + @color = color + @diameter = diameter end end @@ -61,7 +92,7 @@ def tree_data diameter_sum += apple.diameter end - avg_diameter = # It's up to you to calculate the average diameter for this harvest. + avg_diameter = diameter_sum / basket.count puts "Year #{tree.age} Report" puts "Tree height: #{tree.height} feet" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..bf6db62 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,3 @@ +RSpec.configure do |config| + config.warnings = true +end diff --git a/spec/tree_spec.rb b/spec/tree_spec.rb index 99c9184..60016bd 100644 --- a/spec/tree_spec.rb +++ b/spec/tree_spec.rb @@ -1,14 +1,165 @@ require 'rspec' require 'tree' -describe 'Tree' do +def apple(params = {}) + defaults = { + color: "red", + diameter: 3 + } + + Apple.new(**defaults.merge(params)) +end + +def tree(params = {}) + defaults = { + height: 20, + age: 10, + apples: [apple(diameter: 3), + apple(diameter: 2), + apple(diameter: 3)], + alive: true + } + + Tree.new(**defaults.merge(params)) +end + +describe Tree do it 'should be a Class' do - expect(described_class.is_a? 'Class').to be_true + expect(described_class.is_a? Class).to be true + end + + it 'has a height' do + expect(tree(height: 15).height).to eq(15) + end + + it 'has an age' do + expect(tree(age: 75).age).to eq(75) + end + + context 'is alive' do + subject { tree } + + it 'can have apples' do + expect(tree.any_apples?).to be true + end + + it 'can have no apples' do + expect(tree(apples: []).any_apples?).to be false + end + + it 'can grow apples' do + original_apples_count = subject.apples.count + subject.add_apples + new_apples_count = subject.apples.count + expect(original_apples_count).to be < new_apples_count + end + + context 'has apples' do + it 'can be picked' do + picked_apple = subject.pick_an_apple! + expect(picked_apple.class).to eq(Apple) + end + end + + context 'has no apples' do + subject { tree(apples: []) } + + it 'cannot be picked' do + expect { subject.pick_an_apple! }.to raise_error(NoApplesError) + end + end + + context 'is less than 25 feet tall' do + it 'can grow taller' do + original_tree_height = subject.height + subject.age! + new_tree_height = subject.height + expect(original_tree_height).to be < new_tree_height + end + end + + context 'is 25 feet tall' do + subject { tree(height: 25) } + + it 'cannot grow taller' do + original_tree_height = subject.height + subject.age! + new_tree_height = subject.height + expect(original_tree_height).to eq new_tree_height + end + end + + context 'is less than 200 years old' do + it 'can grow older' do + original_tree_age = subject.age + subject.age! + new_tree_age = subject.age + expect(original_tree_age).to be < new_tree_age + end + end + + context 'is 200 years old' do + subject { tree(age: 200) } + + it 'dies' do + subject.age! + expect(subject.dead?).to be true + end + end + end + + before(:context) do + @dead_tree = tree + @dead_tree.kill! + end + + context 'is dead' do + it 'cannot age' do + expect { @dead_tree.age! }.to raise_error(DeadTreeError) + end + + it 'has no apples' do + expect(@dead_tree.apples.count).to eq(0) + end + + it 'cannot grow apples' do + expect { @dead_tree.add_apples }.to raise_error(DeadTreeError) + end + + it 'cannot be picked' do + expect { @dead_tree.pick_an_apple! }.to raise_error(DeadTreeError) + end end end -describe 'Fruit' do +describe Fruit do + it 'should be a Class' do + expect(described_class.is_a? Class).to be true + end + + it 'has seeds' do + expect(Fruit.new.has_seeds?).to be true + end end -describe 'Apple' do +describe Apple do + it 'should be a Class' do + expect(described_class.is_a? Class).to be true + end + + it 'should be a Fruit' do + expect(described_class.superclass).to eq(Fruit) + end + + it 'has a color' do + expect(apple(color: "green").color).to eq("green") + end + + it 'has a diameter' do + expect(apple(diameter: 2).diameter).to eq(2) + end + + it 'has seeds' do + expect(apple.has_seeds?).to be true + end end