Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sample tests written with Bacon #117

Open
amirrajan opened this issue Dec 16, 2018 · 2 comments

Comments

Projects
None yet
1 participant
@amirrajan
Copy link
Owner

commented Dec 16, 2018

Here are some sample tests written with bacon. Feel free to add your own.

@amirrajan

This comment has been minimized.

Copy link
Owner Author

commented Dec 16, 2018

module ADR
describe "rules of world events" do
  [
    { :type => SwampEvent },
    { :type => ShipEvent },
    { :type => IronMineEvent },
    { :type => SulphurMineEvent },
    { :type => HouseEvent },
    { :type => CoalMineEvent },
    { :type => CaveEvent },
    { :type => BattlefieldEvent },
    { :type => BoreholeEvent },
    {
      :type => TownEvent,
      :rolls => [
        # a1    b1    c1    d1    end1
        [ 0.35, 0.45, 0.45, 0.45, 0.45 ],

        # a1    b1    c1    d1    end2
        [ 0.35, 0.45, 0.45, 0.45, 0.95 ],

        # a1    b2    c2    d1    end2
        [ 0.35, 0.95, 0.45, 0.45, 0.95 ],

        # a1    b2    c3    d1    end2
        [ 0.35, 0.95, 0.95, 0.45, 0.95 ],

        # a2    b3    c4    d2    end3
        [ 0.95, 0.45, 0.45, 0.45, 0.45 ],

        # a2    b4    c5    d2    end4
        [ 0.95, 0.95, 0.45, 0.45, 0.95 ],

        # a2    b4    c6    d2    end4
        [ 0.95, 0.95, 0.95, 0.45, 0.95 ],
      ]
    },
    {
      :type => CityEvent,
      :rolls => [
        # a1    b1    c1    d1    end1
        [ 0.35, 0.45, 0.45, 0.45, 0.45 ],

        # a1    b2    c2    d2    end2
        [ 0.35, 0.95, 0.45, 0.95, 0.95 ],

        # a1    b2    c3    d3    end3
        [ 0.35, 0.95, 0.95, 0.95, 0.95 ],

        # a2    b3    c4    d4    end4
        [ 0.75, 0.45, 0.45, 0.45, 0.45 ],

        # a2    b3    c4    d5    end5
        [ 0.75, 0.45, 0.45, 0.95, 0.95 ],

        # a2    b3    c5    d5    end5
        [ 0.75, 0.45, 0.95, 0.95, 0.95 ],

        # a2    b4    c5    d5    end5
        [ 0.75, 0.95, 0.45, 0.45, 0.45 ],

        # a2    b4    c6    d5    end5
        [ 0.75, 0.95, 0.95, 0.45, 0.45 ],

        # a2    b4    c6    d6    end5
        [ 0.75, 0.95, 0.95, 0.95, 0.45 ],

        # a2    b4    c6    d6    end6
        [ 0.75, 0.95, 0.95, 0.95, 0.95 ],

        # a3    b5    c7    d7    end7
        [ 0.95, 0.45, 0.45, 0.45, 0.45 ],

        # a3    b5    c7    d7    end8
        [ 0.95, 0.45, 0.45, 0.45, 0.95 ],

        # a3    b5    c7    d8    end8
        [ 0.95, 0.45, 0.45, 0.95, 0.95 ],

        # a3    b6    c8    d8    end8
        [ 0.95, 0.95, 0.45, 0.95, 0.95 ],

        # a3    b6    c9    d9    end9
        [ 0.95, 0.95, 0.95, 0.95, 0.95 ],
      ]
    },
  ].each do |row|
    it "#{row[:type]}: each scene contains two or fewer options" do
      for_all_scenes_of row[:type], row[:rolls] do |event|
        current_scene(event).should have_one_or_two_options
      end
    end

    it "#{row[:type]}: each scene has text associated with it" do
      for_all_scenes_of row[:type], row[:rolls] do |event|
        current_scene(event)[:text].class.should.equal Array
      end
    end

    it "#{row[:type]}: loot scenes either have a continue and run, or leave option" do
      for_all_scenes_of row[:type], row[:rolls] do |event|
        if current_scene(event)[:loot]
          current_scene(event).should have_loot_specific_options
        end
      end
    end

    it "#{row[:type]}: clears the event at the end (or becomes and outpost)" do
      for_each_completion_of row[:type], row[:rolls] do |world, event|
        if event.becomes_outpost?
          world.landmarks[[30,30]].should.equal :outpost
        elsif event.on_clear_replace_with
          world.landmarks[[30,30]].should.equal event.on_clear_replace_with
        else
          world.cleared[[30,30]].should.equal true
        end
      end
    end

    it "#{row[:type]}: combat scenes only have continue and run" do
      for_all_scenes_of row[:type], row[:rolls] do |event|
        if current_scene(event)[:combat]
          current_scene(event).should have_combat_specific_options
        end
      end
    end

    it "#{row[:type]}: accounts for all scenes" do
      all_scenes = []

      for_all_scenes_of row[:type], row[:rolls] do |event|
        all_scenes << event.current_scene
      end

      event = row[:type].new(game_ready_to_play)
      event.init_scenes
      event.scenes.keys.sort.should.equal all_scenes.uniq.sort
    end
  end

  def for_each_completion_of type, rolls = nil
    game = game_ready_to_play
    event = type.new game
    event.init_scenes
    rolls ||= rolls_for event

    rolls.each do |roll|
      game = game_ready_to_play
      event = type.new game
      event.init_scenes
      turn_index = 0
      Event.stub_roll roll[turn_index]

      until move_forward(event) == :end
        turn_index += 1

        if roll[turn_index] != nil
          Event.stub_roll roll[turn_index]
        end
      end

      yield game.world, event
    end

    "no op".should.equal "no op" #prevents empty specification warning
  end

  def for_all_scenes_of type, rolls
    game = game_ready_to_play
    event = type.new game
    event.init_scenes
    rolls ||= rolls_for event

    rolls.each do |roll|
      game = game_ready_to_play
      event = type.new game
      event.init_scenes
      turn_index = 0
      Event.stub_roll roll[turn_index]

      yield event

      while move_forward(event) != :end
        turn_index += 1

        if roll[turn_index] != nil
          Event.stub_roll roll[turn_index]
        end

        yield event
      end
    end

    "no op".should.equal "no op" #prevents empty specification warning
  end

  def current_scene event
    event.scenes[event.current_scene]
  end

  def move_forward event
    next_scene = current_scene(event)[:options].keys.first

    event.change_scene next_scene

    event.current_scene
  end

  def rolls_for event
    #this method finds all random rolls needed to traverse the event tree
    #it's my attempt to avoid creating a recursive method that generates the tree
    #and then attempts to traverse it

    rolls = []

    event.scenes.keys.each do |key|
      scene = event.scenes[key]

      scene[:options].keys.each do |option_key|
        option = scene[:options][option_key]

        if option[:next_scene].is_a?(Hash)
          option[:next_scene].keys.each do |roll|
            rolls << [roll - 0.05]
          end
        end
      end
    end

    rolls << [1] if rolls.length == 0

    rolls.uniq
  end

  def have_one_or_two_options
    lambda do |scene|
      if(scene[:options].keys.count == 1 or scene[:options].keys.count == 2)
        true
      else
        raise "Scene #{scene} doesn't have the write amount of options"
      end
    end
  end

  def have_combat_specific_options
    lambda do |scene|
      passed = true

      keys = scene[:options].keys

      if keys.count != 2
        passed = false
        message = "combat scene didn't contain exactly two options"
      end

      if !scene[:max_health] or
        !scene[:health] or
        !scene[:attack_delay] or
        !scene[:enemy] or
        !scene[:damage]
        passed = false
        message = "combat scene is missing max_health, health, enemy, damage or attack delay"
      end

      if keys.first != :continue
        passed = false
        message = "combat scene's first option wasn't continue"
      end

      if keys[-1] != :run
        passed = false
        message = "combat scene's last option wasn't run"
      end

      if !passed
        raise "combat scene doesn't have the right stuff (#{message}) #{scene}"
      end

      passed
    end
  end

  def have_loot_specific_options
    lambda do |scene|
      passed = true
      keys = scene[:options].keys
      message = ""

      if keys.count > 2 or keys.count < 1
        passed = false
        message = "loot options where greater than 2 or less then 1"
      end

      guarenteed_loot = false

      scene[:loot].keys.each do |loot_key|
        if scene[:loot][loot_key][:chance] > 0.98
          guarenteed_loot = true
        end
      end

      if !guarenteed_loot
        passed = false
        message = "loot not guranteed for scene"
      end

      if keys.count == 2
        if keys.first != :continue
          passed = false
          message = "it had two options, but the first option wasn't :continue"
        end

        if keys[-1] != :run
          passed = false
          message = "it had two options, but the last option wasn't :run"
        end
      end

      if keys.count == 1
        if keys.first != :leave
          passed = false
          message = "it had one options, but the option wasn't :leave"
        end
      end

      if !passed
        raise "loot scene doesn't have the right stuff (#{message}) #{scene}"
      end

      passed
    end
  end

  def events
    World.event_map.keys.map { |key| World.event_map[key] }
  end

  def game_ready_to_play
    game = Game.new
    game.load
    game.game_state.clear
    game.room.unlock_forest
    game.room.builder_ready
    game.room.unlock_crafts
    game.world.stores[:torch] = 10000
    game.world.stores[:cure_meat] = 10000
    game.world.stores[:jewel] = 10000
    game
  end
end
end
@amirrajan

This comment has been minimized.

Copy link
Owner Author

commented Dec 16, 2018

module ADR
describe Room do
  before do
    @game = Game.new
    @game.load
    @game.game_state.clear
    @tick_executed = false
  end

  def update
    @tick_executed = true
  end

  it "title is based off of fire" do
    @game.room.title.should.equal "a dark room"
  end

  describe "stoking and lighting fire after forest" do
    before do
      @game = Game.new
      @game.load
      @game.game_state.clear
      @game.room.light_fire
      @game.room.unlock_forest
    end

    it "requires 1 wood to stoke fire" do
      @game.room.stoke_ready_after.times { @game.tick }
      @game.room.begining_of_game.should.equal false
      @game.room.stoke.should.equal true
      @game.stores[:wood].should.equal 3
    end

    it "isn't preformed if there aren't enough funds" do
      @game.room.stoke_ready_after.times { @game.tick }
      @game.stores[:wood] = 0
      @game.room.stoke.should.equal false
    end

    it "requires 5 wood to light fire" do
      @game.room.fire = :dead
      @game.room.light_fire.should.equal false
      @game.stores[:wood] = 10
      @game.room.light_fire.should.equal true
      @game.stores[:wood].should.equal 5
    end
  end

  describe "starting and stoking fire" do
    it "a fire can be lit" do
      @game.room.light_fire
      @game.room.fire.should.equal :burning
    end

    it "allows stoking after a timer interval has passed" do
      @game.room.light_fire

      @game.room.can_stoke?.should.equal false

      @game.room.stoke_ready_after.times do |i|
        @game.room.current_stoke_ticks.should.equal i
        @game.tick
      end

      @game.room.can_stoke?.should.equal true
    end

    it "stoke is ignored if it cannot stoke" do
      @game.room.light_fire

      @game.room.can_stoke?.should.equal false

      @game.room.stoke

      @game.room.fire.should.equal :burning
    end

    it "current stoke ticks doesn't surpass ready ticks" do
      @game.room.light_fire

      (@game.room.stoke_ready_after + 1).times do |i|
        @game.tick
      end

      @game.room.current_stoke_ticks.should.equal @game.room.stoke_ready_after
    end

    it "stoke ticks remains zero if fire is dead" do
      @game.tick

      @game.room.current_stoke_ticks.should.equal 0
    end

    it "stoking interval and fire status increase reset after stoking" do
      @game.room.light_fire
      @game.room.stoke_ready_after.times { @game.tick }
      @game.room.stoke
      @game.room.fire.should.equal :roaring
      @game.room.can_stoke?.should.equal false
    end

    it "initialize the game with fire state" do
      @game.room.tick

      fire_history.last.should.equal "the fire is dead."
    end

    it "notifies the state of the fire" do
      @game.room.light_fire

      @game.room.tick

      fire_history.last.should.equal "the fire is burning."
    end

    it "records fire state everytime the fire is stoked" do
      @game.tick
      @game.room.light_fire
      @game.room.stoke_ready_after.times { @game.tick }
      @game.room.stoke
      @game.room.stoke_ready_after.times { @game.tick }
      @game.room.stoke
      @game.tick

      fire_history[0].should.equal "the fire is dead."
      fire_history[1].should.equal "the fire is burning."
      fire_history[2].should.equal "the fire is roaring."
      fire_history[3].should.equal "the fire is roaring."
    end

    def fire_history
      @game.history.select { |h| h.match /^the fire/ }
    end
  end

  describe "cooling fire" do
    it "cools if it hasn't been stoked" do
      @game.room.light_fire
      @game.room.stoke_ready_after.times { @game.tick }
      @game.room.stoke
      @game.room.fire.should.equal :roaring
      @game.room.cool_fire_after.times { @game.tick }
      @game.room.fire.should.equal :burning
      @game.room.cool_fire_after.times { @game.tick }
      @game.room.fire.should.equal :flickering
      @game.room.cool_fire_after.times { @game.tick }
      @game.room.fire.should.equal :smoldering
      @game.room.cool_fire_after.times { @game.tick }
      @game.room.fire.should.equal :dead
      @game.room.cool_fire_after.times { @game.tick }
      @game.room.fire.should.equal :dead
    end

    it "resets cooling if fire is stoked" do
      @game.room.light_fire
      @game.room.stoke_ready_after.times { @game.tick }
      @game.room.stoke
      @game.room.fire.should.equal :roaring
      (@game.room.cool_fire_after - 1).times { @game.tick }
      @game.room.stoke
      (@game.room.cool_fire_after - 1).times { @game.tick }
      @game.room.fire.should.equal :roaring
    end
  end

  it "scripted unlock of forest" do
    @game.room.light_fire

    @game.room.builder_status_change_after.times { @game.tick }

    @game.room.forest_unlocked?.should.equal false

    @game.room.builder_status_change_after.times { @game.tick }

    @game.room.forest_unlocked?.should.equal true

    @game.stores[:wood].should.equal 4
  end

  describe "room heating" do
    it "room heats up relative to fire's current state, but doesn't move past" do
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :freezing
      @game.room.light_fire
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :cold
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :mild
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :warm
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :warm

      @game.room.stoke
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :hot
    end

    it "records temp changes" do
      @game.tick
      @game.room.light_fire
      @game.room.room_temp_changes_after.times { @game.tick }

      temperature_history[0].should.equal "the room is cold."
      temperature_history[1].should.equal "the room is mild."
    end

    it "records cooling temperatures" do
      @game.tick
      @game.room.light_fire
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :warm
      @game.room.stoke

      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :hot

      @game.room.cool_fire_after.times { @game.tick }
      @game.room.fire.should.equal :burning

      @game.room.room_temp_changes_after.times { @game.tick }
      @game.room.temperature.should.equal :warm

      temperature_history.last.should.equal "the room is warm."
    end

    def temperature_history
      @game.history.select { |h| h.match /the room/ }
    end
  end

  it "builder squence" do
    @game.room.light_fire

    @game.room.builder_status_change_after.times { @game.tick }

    @game.history
      .select { |h| h.match /from the windows/ }
      .first
      .should
      .equal "the light from the fire spills from the windows, out into the dark."

    @game.room.builder_status_change_after.times { @game.tick }

    @game.history
      .select { |h| h.match /stumbles/ }
      .count.should.equal 1

    @game.room.room_temp_changes_after.times { @game.tick }
    @game.room.builder_status_change_after.times { @game.tick }

    @game.history
      .select { |h| h.match /mumbles/ }
      .count.should.equal 1

    @game.room.builder_status_change_after.times { @game.tick }

    @game.history
      .select { |h| h.match /calms/ }
      .count.should.equal 1
  end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.