Skip to content

Commit

Permalink
adding profile object and improving game class and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanb committed Jul 12, 2008
1 parent d5415f8 commit 5c033fe
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 4 deletions.
1 change: 1 addition & 0 deletions bin/rubywarrior
Expand Up @@ -2,5 +2,6 @@
require File.dirname(__FILE__) + '/../lib/ruby_warrior'

RubyWarrior::UI.out_stream = STDOUT
RubyWarrior::UI.in_stream = STDIN
game = RubyWarrior::Game.new # TODO pass options into game when initializing
game.start
1 change: 1 addition & 0 deletions lib/ruby_warrior.rb
@@ -1,6 +1,7 @@
$: << File.dirname(__FILE__)

require 'ruby_warrior/game'
require 'ruby_warrior/profile'
require 'ruby_warrior/ui'
require 'ruby_warrior/player_generator'
require 'ruby_warrior/level_builder'
Expand Down
52 changes: 52 additions & 0 deletions lib/ruby_warrior/game.rb
Expand Up @@ -60,5 +60,57 @@ def tower
def player_path
"ruby-warrior/#{tower_name}-tower"
end



# ensure the ruby-warrior directory exists and ask to create it if not
def make_game_directory
if UI.request_boolean("No ruby-warrior directory found, would you like to create one?")
Dir.mkdir('ruby-warrior')
else
UI.puts "Unable to continue without directory."
exit
end
end


# profiles

def profiles
profile_paths.map { |profile| Profile.load(profile) }
end

def profile_paths
Dir['ruby-warrior/**/.profile']
end

def profile
if profiles.empty?
new_profile
else
profile = UI.choose(profiles + [[:new, 'New Profile']])
if profile == :new
new_profile
else
profile
end
end
end

def new_profile
Profile.new(UI.choose(towers), UI.request('Enter a name for your warrior: '))
end


# towers

def towers
tower_paths.map { |tower| Tower.load(tower) }
end

def tower_paths
Dir[File.expand_path(File.dirname(__FILE__) + '/../../towers/*')]
end

end
end
7 changes: 7 additions & 0 deletions lib/ruby_warrior/profile.rb
@@ -0,0 +1,7 @@
module RubyWarrior
class Profile
def initialize(tower, name)

end
end
end
4 changes: 4 additions & 0 deletions lib/ruby_warrior/tower.rb
Expand Up @@ -2,6 +2,10 @@ module RubyWarrior
class Tower
attr_reader :name

def self.load(path)
# TODO
end

def initialize(name)
@name = name
end
Expand Down
43 changes: 39 additions & 4 deletions lib/ruby_warrior/ui.rb
@@ -1,15 +1,50 @@
module RubyWarrior
class UI
def self.in_stream=(in_stream)
@in = in_stream
end

def self.out_stream=(stream)
@out = stream
end

def self.out
@out ||= StringIO.new
def self.puts(msg)
@out.puts(msg) if @out
end

def self.print(msg)
@out.print(msg) if @out
end

def self.puts(msg)
out.puts(msg)
def self.gets
@in.gets if @in
end

def self.request(msg)
print(msg)
gets
end

def self.ask(msg)
request("#{msg} [yn] ") == 'y'
end

# REFACTORME
def self.choose(options)
options.each_with_index do |option, i|
if option.kind_of? Array
puts "[#{i+1}] #{option.last}"
else
puts "[#{i+1}] #{option}"
end
end
choice = request('Choose an option by typing the number: ')
response = options[choice.to_i-1]
if response.kind_of? Array
response.first
else
response
end
end
end
end
78 changes: 78 additions & 0 deletions spec/ruby_warrior/game_spec.rb
Expand Up @@ -9,4 +9,82 @@
@game.stubs(:tower_name).returns('foo')
@game.player_path.should == 'ruby-warrior/foo-tower'
end


# GAME DIR

it "should make game directory if player says so" do
RubyWarrior::UI.stubs(:request_boolean).returns(true)
Dir.expects(:mkdir).with('ruby-warrior')
@game.make_game_directory
end

it "should not make game and exit if player says no" do
RubyWarrior::UI.stubs(:request_boolean).returns(false)
Dir.stubs(:mkdir).raises('should not be called')
lambda { @game.make_game_directory }.should raise_error(SystemExit)
end


# PROFILES

it "should load profiles for each profile path" do
RubyWarrior::Profile.expects(:load).with('foo/.profile').returns(1)
RubyWarrior::Profile.expects(:load).with('bar/.profile').returns(2)
@game.stubs(:profile_paths).returns(['foo/.profile', 'bar/.profile'])
@game.profiles.should == [1, 2]
end

it "should find profile paths using Dir[] search" do
Dir.expects(:[]).with("ruby-warrior/**/.profile")
@game.profile_paths
end

it "should try to create profile when no profile paths are specified" do
@game.stubs(:profiles).returns([])
@game.expects(:new_profile).returns('profile')
@game.profile.should == 'profile'
end

it "should ask a player to choose a profile if multiple profiles are available" do
RubyWarrior::UI.expects(:choose).with([:profile1, [:new, 'New Profile']]).returns(:profile1)
@game.stubs(:profiles).returns([:profile1])
@game.profile.should == :profile1
end

it "should make a new profile if player chooses" do
RubyWarrior::UI.expects(:choose).returns(:new)
@game.stubs(:profiles).returns([:profile1])
@game.expects(:new_profile).returns('new_profile')
@game.profile.should == 'new_profile'
end

it "should ask user to choose a tower when creating a new profile" do
@game.stubs(:towers).returns([:tower1, :tower2])
RubyWarrior::UI.expects(:choose).with([:tower1, :tower2])
@game.new_profile
end

it "should pass name and selected tower to profile" do
RubyWarrior::UI.stubs(:choose).returns('tower')
RubyWarrior::UI.stubs(:request).returns('name')
RubyWarrior::Profile.expects(:new).with('tower', 'name').returns('profile')
@game.new_profile.should == 'profile'
end


# TOWERS

it "load towers for each tower path" do
RubyWarrior::Tower.expects(:load).with('towers/foo').returns(1)
RubyWarrior::Tower.expects(:load).with('towers/bar').returns(2)
@game.stubs(:tower_paths).returns(['towers/foo', 'towers/bar'])
@game.towers.should == [1, 2]
end

it "should find tower paths using Dir[] search" do
Dir.expects(:[]).with(File.expand_path(File.dirname(__FILE__) + '/../../towers/*'))
@game.tower_paths
end

end
5 changes: 5 additions & 0 deletions spec/ruby_warrior/profile_spec.rb
@@ -0,0 +1,5 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe RubyWarrior::Profile do

end
63 changes: 63 additions & 0 deletions spec/ruby_warrior/ui_spec.rb
@@ -0,0 +1,63 @@
require File.dirname(__FILE__) + '/../spec_helper'

describe RubyWarrior::UI do
before(:each) do
@ui = RubyWarrior::UI
@out = StringIO.new
@in = StringIO.new
@ui.out_stream = @out
@ui.in_stream = @in
end

it "should add puts to out stream" do
@ui.puts "hello"
@out.string.should == "hello\n"
end

it "should add print to out stream without newline" do
@ui.print "hello"
@out.string.should == "hello"
end

it "should fetch gets from in stream" do
@in.puts "bar"
@in.rewind
@ui.gets.should == "bar\n"
end

it "should request text input" do
@in.puts "bar"
@in.rewind
@ui.request("foo").should == "bar\n"
@out.string.should == "foo"
end

it "should ask for yes/no and return true when yes" do
@ui.expects(:request).with('foo? [yn] ').returns('y')
@ui.ask("foo?").should be_true
end

it "should ask for yes/no and return false when no" do
@ui.stubs(:request).returns('n')
@ui.ask("foo?").should be_false
end

it "should ask for yes/no and return false for any input" do
@ui.stubs(:request).returns('aklhasdf')
@ui.ask("foo?").should be_false
end

it "should present multiple options and return selected one" do
@ui.stubs(:request).returns('2')
@ui.choose([:foo, :bar, :test]).should == :bar
@out.string.should include('[1] foo')
@out.string.should include('[2] bar')
@out.string.should include('[3] test')
end

it "choose should accept array as option" do
@ui.stubs(:request).returns('3')
@ui.choose([:foo, :bar, [:tower, 'easy']]).should == :tower
@out.string.should include('[3] easy')
end
end

0 comments on commit 5c033fe

Please sign in to comment.