diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bec022 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.bundle/ +.vscode/ +bin/ \ No newline at end of file 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 962b72e..0f39b99 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,44 +1,77 @@ class NoApplesError < StandardError; end +# A class representing an apple tree class Tree - attr_#fill_in :height, :age, :apples, :alive - - def initialize + MAX_AGE = 20 + FRUIT_AGE = 2 + GROWTH_PER_YEAR = 2 # inches + + attr_accessor :height, :age, :apples, :alive + + def initialize(height = 0, age = 0, apples = [], alive = true) + @height = height + @age = age + @apples = apples + @alive = alive + @death_age = rand(0..Tree::MAX_AGE) end def age! + if @age < @death_age + @age += 1 + @height += Tree::GROWTH_PER_YEAR + if @age > Tree::FRUIT_AGE + 20.times do + @apples << Apple.new('red', rand(1..4)) + end + end + else + @alive = false + end end - def add_apples + def add_apples(apples) + if apples.is_a? Apple + @apples << apples + elsif apples.is_a? Array + @apples += apples + end end def any_apples? + !@apples.empty? end def pick_an_apple! - raise NoApplesError, "This tree has no apples" unless self.any_apples? + raise NoApplesError, 'This tree has no apples' unless any_apples? + @apples.pop end def dead? + !@alive end end +# Base class for fruits, which all have seeds. class Fruit def initialize has_seeds = true end end -class Apple < - attr_reader #what should go here +# Class representing an Apple, which derives from Fruit, if you didn't know. +class Apple < Fruit + attr_reader :color, :diameter def initialize(color, diameter) + @color = color + @diameter = diameter end end -#THERES ONLY ONE THING YOU NEED TO EDIT BELOW THIS LINE -# avg_diameter (line 58) will raise an error. -# it should calculate the diameter of the apples in the basket +# THERES ONLY ONE THING YOU NEED TO EDIT BELOW THIS LINE +# avg_diameter (line 58) will raise an error. +# it should calculate the diameter of the apples in the basket def tree_data tree = Tree.new @@ -61,19 +94,22 @@ def tree_data diameter_sum += apple.diameter end - avg_diameter = # It's up to you to calculate the average diameter for this harvest. + # It's up to you to calculate the average diameter for this harvest. + avg_diameter = diameter_sum / basket.size.to_f puts "Year #{tree.age} Report" puts "Tree height: #{tree.height} feet" puts "Harvest: #{basket.size} apples with an average diameter of #{avg_diameter} inches" - puts "" + puts '' # Ages the tree another year tree.age! end - puts "Alas, the tree, she is dead!" + puts 'Alas, the tree, she is dead!' end -# Uncomment this line to run the script, but BE SURE to comment it before you try to run your tests! -# tree_data +# Uncomment this line to run the script, but BE SURE to comment it before you +# try to run your tests! + +tree_data diff --git a/spec/tree_spec.rb b/spec/tree_spec.rb index 6394020..285c51a 100644 --- a/spec/tree_spec.rb +++ b/spec/tree_spec.rb @@ -1,14 +1,128 @@ require 'rspec' -require 'tree' +# require 'pry' +require_relative '../lib/tree' describe Tree do it 'should be a Class' do - expect(described_class.is_a? Class).to eq true + expect(described_class.is_a?(Class)).to eq true + end + + describe '#initialize' do + tree = Tree.new + + it 'should default height to 0' do + expect(tree.height).to eq(0) + end + + it 'should default age to 0' do + expect(tree.age).to eq(0) + end + + it 'should be alive' do + expect(tree.alive).to eq(true) + end + + it "shouldn't have any apples" do + expect(tree.apples.size).to eq(0) + end + end + + describe '#age!' do + it 'should increase the age by one year' do + tree = Tree.new + tree.age! + expect(tree.age).to eq(1) + tree.age! + expect(tree.age).to eq(2) + end + + it 'should increase the height by Tree::GROWTH_PER_YEAR' do + tree = Tree.new + tree.age! + expect(tree.height).to eq(Tree::GROWTH_PER_YEAR) + tree.age! + expect(tree.height).to eq(Tree::GROWTH_PER_YEAR * 2) + end + end + + describe '#add_apples' do + it 'should add the specified apples to the tree' do + red_apple = Apple.new('red', 1) + green_apple = Apple.new('green', 2) + tree = Tree.new + tree.add_apples([red_apple, green_apple]) + expect(tree.apples.size).to eq(2) + expect(tree.apples[0]).to eq(red_apple) + expect(tree.apples[1]).to eq(green_apple) + end + + it 'should allow a single apple to be added to the tree' do + red_apple = Apple.new('red', 1) + tree = Tree.new + tree.add_apples(red_apple) + expect(tree.apples.size).to eq(1) + expect(tree.apples[0]).to eq(red_apple) + end + end + + describe '#any_apples?' do + it 'should return false for a new Tree without apples' do + tree = Tree.new + expect(tree.any_apples?).to eq(false) + end + + it 'should return true for a Tree that has apples' do + tree = Tree.new + tree.add_apples Apple.new('red', 1) + expect(tree.any_apples?).to eq(true) + end + end + + describe '#pick_an_apple!' do + tree = Tree.new + it 'should raise an exception for a Tree without apples' do + expect { tree.pick_an_apple! }.to raise_error(NoApplesError) + end + + red_apple = Apple.new('red', 1) + it 'should return an apple for a Tree with apples' do + tree.add_apples(red_apple) + expect(tree.pick_an_apple!).to eq(red_apple) + end + + it 'should decrement the number of apples in the tree' do + tree.add_apples(red_apple) + tree.pick_an_apple! + expect(tree.apples.size).to eq(0) + end + end + + describe '#dead?' do + it 'should return false if the Tree is alive' do + expect(Tree.new.dead?).to eq(false) + end + + it 'should return true if the Tree is not alive' do + dead_yearling = Tree.new(2, 1, [], false) + expect(dead_yearling.dead?).to eq(true) + end end end -describe 'Fruit' do +describe Fruit do + it 'should be a Class' do + expect(described_class.is_a?(Class)).to eq true + end end -describe 'Apple' do +describe Apple do + let(:apple) { described_class.new('red', 10) } + + it 'should be a Class' do + expect(described_class.is_a?(Class)).to eq true + end + + it 'should be a Fruit' do + expect(apple.is_a?(Fruit)).to eq true + end end