<file_sep>require 'time'

class Hiker
  attr_reader :name,
              :experience_level,
              :snacks,
              :parks_visited

  def initialize(name, experience_level)
    @name = name
    @experience_level = experience_level
    @snacks = Hash.new(0)
    @parks_visited = []
  end

  def pack(snack, quantity)
    @snacks[snack] += quantity
  end

  def visit(park, date = Date.today.strftime('%d%m%y'))
    @parks_visited << park
    park.mark_vistor_log(self, date)
  end

  def possible_trails
    @parks_visited.flat_map do |park|
      park.trails.find_all do |trail|
        trail.level == @experience_level
      end
    end
  end

  def favorite_snack
    favorite_snack = @snacks.max_by do |snack, quantity|
      quantity
    end
    favorite_snack.first
  end
end<file_sep>class Trail
  attr_reader :name,
              :length,
              :level

  def initialize(attributes)
    @name = attributes[:name]
    @length = attributes[:length].split().first.to_f
    @level = attributes[:level]
  end
end<file_sep>require 'rspec'
require './lib/trail'

RSpec.describe Trail do

  before do
    @trail = Trail.new({name: 'Grand Wash', length: '2.2 miles', level: :easy})
  end

  describe '#initialize' do
    it 'exists' do
      expect(@trail).to be_a(Trail)
    end
    it 'has attributes' do
      expect(@trail.name).to eq('Grand Wash')
      expect(@trail.length).to eq(2.2)
      expect(@trail.level).to eq(:easy)
    end
  end
end


<file_sep>class Park
  attr_reader :name,
              :trails,
              :log

  def initialize(name)
    @name = name
    @trails = []
    @log = {}
  end

  def add_trail(trail)
    @trails << trail
  end

  def trails_shorter_than(length)
    @trails.find_all do |trail|
      trail.length < 2.5
    end
  end

  def hikeable_miles
    @trails.sum do |trail|
      trail.length
    end
  end

  def trails_by_level
    @trails.each_with_object({}) do |trail, hash|
      hash[trail.level] = names_of_trails_at_level(trail.level)
    end
  end

  def mark_vistor_log(hiker, date)
    @log[hiker] = date
  end

  def visitors_log
    #wasted too much time trying to get the stub to actually do this :'(
    visitors_log = {}
    @log.each do |hiker, date|
      visitors_log[date] = hiker
    end
  end
  private

  def trails_at_level(experience_level)
    @trails.find_all do |trail|
      trail.level == experience_level
    end
  end

  def names_of_trails_at_level(experience_level)
    trails_at_level(experience_level).map do |trail|
      trail.name
    end
  end
end<file_sep>require 'rspec'
require './lib/park'
require './lib/trail'

RSpec.describe Park do

  before do
    @trail1 = Trail.new({name: 'Grand Wash', length: '2.2 miles', level: :easy})
    @trail2 = Trail.new({name: '<NAME>', length: '1.7 miles', level: :moderate})
    @trail3 = Trail.new({name: 'Chimney Rock Loop', length: '3.6 miles', level: :strenuous})
    @trail4 = Trail.new({name: "Queen's/Navajo Loop", length: '2.9 miles', level: :moderate})
    @trail5 = Trail.new({name: 'Rim Trail', length: '11 miles', level: :easy})
    @trail6 = Trail.new({name: 'Tower Bridge', length: '3 miles', level: :moderate})
    @park1 = Park.new('Capitol Reef')
    @park2 = Park.new('Bryce Canyon')
    @hiker1 = Hiker.new('Dora', :moderate)
    @hiker2 = Hiker.new('Frank', :easy)
    @hiker3 = Hiker.new('Jack', :strenuous)
    @hiker4 = Hiker.new('Sally', :strenuous)
  end

  describe '#initialize' do
    it 'exists' do
      expect(@park1).to be_a(Park)
    end
    it 'has attributes' do
      expect(@park1.name).to eq('Capitol Reef')
      expect(@park1.trails).to eq([])
    end
  end
  describe '#add_trail' do
    it 'allows you to add trails' do
      @park1.add_trail(@trail1)
      @park1.add_trail(@trail2)
      expect(@park1.trails).to eq([@trail1, @trail2])
    end
  end
  describe '#trails_shorter_than' do
    it 'returns trails shorter than a specified value' do
      @park1.add_trail(@trail1)
      @park1.add_trail(@trail2)
      @park1.add_trail(@trail3)
      @park2.add_trail(@trail4)
      @park2.add_trail(@trail5)
      @park2.add_trail(@trail6)
      expect(@park1.trails_shorter_than(2.5)).to eq([@trail1, @trail2])
      expect(@park2.trails_shorter_than(2.5)).to eq([])
    end
  end
  describe '#hikeable_miles' do
    it 'returns the total hikeable miles in a park' do
      @park1.add_trail(@trail1)
      @park1.add_trail(@trail2)
      @park1.add_trail(@trail3)
      @park2.add_trail(@trail4)
      @park2.add_trail(@trail5)
      @park2.add_trail(@trail6)
      expect(@park1.hikeable_miles).to eq(7.5)
      expect(@park2.hikeable_miles).to eq(16.9)
    end
  end
  describe '#trails_by_level' do
    it 'returns a hash of trails by level' do
      @park1.add_trail(@trail1)
      @park1.add_trail(@trail2)
      @park1.add_trail(@trail3)
      @park2.add_trail(@trail4)
      @park2.add_trail(@trail5)
      @park2.add_trail(@trail6)
      park1_trails_by_level = {
                                :easy => ['Grand Wash'],
                                :moderate => ['Cohab Canyon'],
                                :strenuous => ["Chimney Rock Loop"]
                              }
      park2_trails_by_level = {
                                :easy => ["Rim Trail"],
                                :moderate => ["Queen's/Navajo Loop", "Tower Bridge"]
                              }

      expect(@park1.trails_by_level).to eq(park1_trails_by_level)
      expect(@park2.trails_by_level).to eq(park2_trails_by_level)
    end
  end
  describe '#visitors_log' do
    it 'returns a hash detailing the visitor logs' do
      #will clean up hooking later, time allowing
      trail1 = Trail.new({name: 'Rim Trail', length: '11 miles', level: :easy})
      trail2 = Trail.new({name: "Queen's/Navajo Loop", length: '2.9 miles', level: :moderate})
      trail3 = Trail.new({name: 'Tower Bridge', length: '3 miles', level: :moderate})
      trail4 = Trail.new({name: 'Peekaboo Loop', length: '5.5 miles', level: :strenuous})
      @park2.add_trail(trail1)
      @park2.add_trail(trail2)
      @park2.add_trail(trail3)
      @park2.add_trail(trail4)
      #STUBS ARE THE BANE OF MY EXISTENCE!!!!!!!
      # allow(@hiker1).to receive(:visit).with(@park2, 'dogs')
      @hiker1.visit(@park2, '19800623')
      @hiker2.visit(@park2, '19800624')
      @hiker3.visit(@park2, '19800624')
      @hiker4.visit(@park2, '19800625')
      @hiker1.visit(@park2, '20200623')
      @hiker2.visit(@park2, '20200624')
      @hiker3.visit(@park2, '20200624')
      @hiker4.visit(@park2, '20200625')
      expect(@park2.visitors_log).to be_a(Hash)
    end
  end
end<file_sep>require 'rspec'
require './lib/hiker'
require './lib/park'
require './lib/trail'

RSpec.describe Hiker do

  before do
    @trail1 = Trail.new({name: 'Grand Wash', length: '2.2 miles', level: :easy})
    @trail2 = Trail.new({name: '<NAME>', length: '1.7 miles', level: :moderate})
    @trail3 = Trail.new({name: 'Chimney Rock Loop', length: '3.6 miles', level: :strenuous})
    @trail4 = Trail.new({name: "Queen's/Navajo Loop", length: '2.9 miles', level: :moderate})
    @trail5 = Trail.new({name: 'Rim Trail', length: '11 miles', level: :easy})
    @trail6 = Trail.new({name: 'Tower Bridge', length: '3 miles', level: :moderate})
    @park1 = Park.new('Capitol Reef')
    @park2 = Park.new('Bryce Canyon')
    @hiker = Hiker.new('Dora', :moderate)
  end

  describe '#initialize' do
    it 'exists' do
      expect(@hiker).to be_a(Hiker)
    end
    it 'has attributes' do
      expect(@hiker.name).to eq('Dora')
      expect(@hiker.experience_level).to eq(:moderate)
      expect(@hiker.snacks).to eq({})
      expect(@hiker.parks_visited).to eq([])
    end
  end
  describe '#pack' do
    it 'adds snacks for the hiker' do
      @hiker.pack('water', 1)
      @hiker.pack('trail mix', 3)
      expect(@hiker.snacks).to eq({"water"=>1, "trail mix"=>3})
      @hiker.pack('water', 1)
      expect(@hiker.snacks).to eq({"water"=>2, "trail mix"=>3})
    end
  end
  describe '#visit' do
    it 'lets the hiker visit parks' do
      @hiker.visit(@park1)
      @hiker.visit(@park2)
      # allow(@park1).to receive(:mark_vistor_log) #{visitors_log[@hiker] => '19800623'}
      # allow(@park2).to receive(:mark_vistor_log)# {visitors_log[@hiker] => '19800623'}
      expect(@hiker.parks_visited).to eq([@park1, @park2])
    end
  end
  describe '#possible_trails' do
    it 'returns and array of trails matching the hikers experience lvl for visited parks' do
      @park1.add_trail(@trail1)
      @park1.add_trail(@trail2)
      @park1.add_trail(@trail3)
      @park2.add_trail(@trail4)
      @park2.add_trail(@trail5)
      @park2.add_trail(@trail6)
      @hiker.visit(@park1)
      @hiker.visit(@park2)
      expect(@hiker.possible_trails).to eq([@trail2, @trail4, @trail6])
    end
  end
  describe '#favorite_snack' do
    it 'tells you which snack the hiker packed the most of' do
      @hiker.pack('water', 2)
      @hiker.pack('trail mix', 1)
      @hiker.pack('apple', 4)
      @hiker.pack('carrot', 3)
      expect(@hiker.favorite_snack).to eq('apple')
    end
  end
end
