Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Cleaned house ! Deleted entire suite, manually verified basic login/l…

…ogout/moving/error reporting was still working in script/server.
  • Loading branch information...
commit 10703b4034bdf10e7b824a6f6eb7d64118214c8b 1 parent 51e8003
@chicagogrooves authored
Showing with 53 additions and 1,451 deletions.
  1. +10 −7 app/controllers/application_controller.rb
  2. +10 −48 app/controllers/authentication_controller.rb
  3. +1 −19 app/controllers/move_controller.rb
  4. +4 −4 app/models/match.rb
  5. +13 −24 app/models/move.rb
  6. +1 −1  app/views/move/_create.html.erb
  7. +1 −0  db/schema.rb
  8. +4 −8 doc/stats.txt
  9. +1 −1  lib/notation.rb
  10. +4 −0 lib/request_smarts.rb
  11. +2 −1  lib/session_smarts.rb
  12. +0 −95 spec/controllers/authentication_controller_spec.rb
  13. +0 −28 spec/controllers/match_controller_fb_spec.rb
  14. +0 −78 spec/controllers/match_controller_spec.rb
  15. +0 −68 spec/controllers/move_controller_spec.rb
  16. +0 −14 spec/controllers/sets_controller_spec.rb
  17. +0 −9 spec/helpers/sets_helper_spec.rb
  18. +0 −120 spec/lib/fen_spec.rb
  19. +0 −32 spec/lib/notation_spec.rb
  20. +0 −87 spec/lib/pgn_spec.rb
  21. +0 −157 spec/models/board_spec.rb
  22. +0 −17 spec/models/chess_notifier_spec.rb
  23. +0 −14 spec/models/fbuser_spec.rb
  24. +0 −25 spec/models/gameplay_spec.rb
  25. +0 −72 spec/models/match_spec.rb
  26. +0 −191 spec/models/move_spec.rb
  27. +0 −87 spec/models/piece_spec.rb
  28. +0 −30 spec/models/player_spec.rb
  29. +0 −67 spec/models/promotion.rb
  30. +0 −18 spec/models/user_spec.rb
  31. +2 −2 spec/spec_helper.rb
  32. +0 −58 test/functional/fbuser_controller_test.rb
  33. +0 −69 test/functional/match_controller_test.rb
View
17 app/controllers/application_controller.rb
@@ -11,20 +11,16 @@ class ApplicationController < ActionController::Base
def extend_session_and_request
s, r, c, p = session, request, cookies, params
r.extend(RequestSmarts)
+ s.extend(SessionSmarts)
r.session, r.cookies, r.params = s, c, p
end
- RequestSmarts.methods_excluding_ancestors.each do |m|
+ # HACK - really re-add params and params= to controller ?
+ RequestSmarts.methods_excluding_ancestors.reject{|m| m.to_s.include?("=")}.each do |m|
helper_method m.to_sym
define_method m do request.send(m) end
end
- # the player this request is being processed for
- def current_player
- @current_player = request.player || player_over_http
- end
- helper_method :current_player
-
# provides basic auth for Curl/Wget functionality
def player_over_http
u = nil
@@ -57,6 +53,13 @@ def player_in_facebook
#only use layout if not a facebook request - todo - standardize the 'is_facebook' test
# layout proc{ |c| c.params[:fb_sig] ? false : 'application' }
+ # the player this request is being processed for
+ def current_player
+ p = request.player || player_over_http
+ request.player = p if p
+ end
+ helper_method :current_player
+
# descendant controllers call authorize to ensure player is logged in, or redirect them to login
def authorize
unless current_player
View
58 app/controllers/authentication_controller.rb
@@ -1,57 +1,19 @@
class AuthenticationController < ApplicationController
- # sets the cookie to track who this stranger is -
- def tag
- cookies[:auth_token] = Digest::MD5.hexdigest(Time.now.to_s)
- redirect_to :action => 'register'
- end
-
- # a tagged visitor can be prompted to register, and their tag will be
- # saved with them, along with any name and password info they have chosen
- # The point of registering, for a facebook user, is so they can have their nickname
- # and a way to login outside of facebook
- def register
- return unless request.post?
-
- params[:user][:auth_token] = cookies[:auth_token]
-
- u = User.create_with_player( params[:user], params[:player] )
-
- if is_facebook?
- fbu = Fbuser.find_or_create_by_facebook_user_id( params[:fb_sig_user] )
- if fbu.new_record?
- fbu.playing_as = u.playing_as
- fbu.save
- end
- end
-
- session[:player_id] = u.playing_as.id
- # current_player = u.playing_as
- redirect_to match_index_url
- end
-
- # allows user to post the credentials they stored to initiate a session
- # an auth token will by default persist their logged in state for as long
- # as the client holds the cookie (it 1 year)
def login
return unless request.post?
- user = User.find_by_email_and_security_phrase( params[:email], params[:security_phrase] )
- flash[:notice] = "Your credentials do not check out." and return unless user
-
- @player = user.playing_as
- session[:player_id] = @player.id
-
- user.auth_token = Digest::MD5.hexdigest(Time.now.to_s)
- user.save!
-
- cookies[:auth_token] = { :value => user.auth_token, :expires => 1.year.from_now }
+ if user = User.find_by_email_and_security_phrase( params[:email], params[:security_phrase] )
+ user.update_attribute(:auth_token, Digest::MD5.hexdigest(Time.now.to_s) )
+ cookies[:auth_token] = { :value => user.auth_token, :expires => 1.year.from_now }
+ request.player = user.playing_as
+ else
+ flash[:notice] = "Your credentials do not check out."
+ return
+ end
- #return them to original page requested
- redirect_to session[:original_uri] and return if session[:original_uri]
-
- #or their homepage
- redirect_to match_index_url and return
+ #return them to original page requested, or their homepage
+ redirect_to session[:original_uri] || match_index_url
end
def logout
View
20 app/controllers/move_controller.rb
@@ -1,8 +1,5 @@
class MoveController < ApplicationController
- rescue_from ArgumentError, :with => :display_error
- rescue_from ActiveRecord::RecordInvalid, :with => :display_error
-
before_filter :authorize
#accessible via get or post but should be idempotent on 2x get
@@ -13,6 +10,7 @@ def create
raise ArgumentError, "It is your not your turn to move yet" unless request.your_turn?
@match.moves << @move = Move.new( params[:move] )
+ flash[:error] = @move.errors.full_messages unless @move.id
# unceremonious way of saying you just ended the game
redirect_to( :controller => 'match', :action => 'index' ) and return unless @match.active
@@ -35,20 +33,4 @@ def create_respond
render :template => 'match/status' and return
end
- def display_error(ex)
- if ex.kind_of?(ArgumentError)
- flash[:move_error] = ex.to_s
- else
- flash[:move_error] = ex.record.moves.last.errors.to_a.map{|e| e[1]}.join "<br/>\n"
- end
-
- #if request.xhr?
- # set_match_status_instance_variables
- # render :template => 'match/status' and return
- #end
-
- redirect_to( match_url(@match.id) ) and return if @match
-
- end
-
end
View
8 app/models/match.rb
@@ -3,8 +3,7 @@ class Match < ActiveRecord::Base
has_many :players, :through => :gameplays
has_many :moves, :before_add => :refer_to_match_instance,
:after_add => [:save_board,
- :check_for_checkmate,
- :play_queued_moves]
+ :check_for_checkmate]
belongs_to :winning_player, :class_name => 'Player', :foreign_key => 'winning_player'
@@ -126,6 +125,8 @@ def checkmate_by( side )
save!
end
+ private
+=begin
# if moves are queued up, looks for matches and plays appropriate responses, or invalidates queue
# for now requires exact match on the notation
def play_queued_moves( m )
@@ -150,10 +151,9 @@ def play_queued_moves( m )
# call it back
play_queued_moves(response_move)
-
end
+=end
- private
def boards_upto_current_move
boards = []
boards << Board.new( self[:start_pos] )
View
37 app/models/move.rb
@@ -4,14 +4,17 @@ class Move < ActiveRecord::Base
include MoveNotation
belongs_to :match
+ belongs_to :player
+
before_save :update_computed_fields
after_save :notify_of_move_via_email
attr_accessor :side
attr_reader :board
- def from_coord_sym; @from_coord_sym = from_coord.to_sym; end
- def to_coord_sym; @to_coord_sym = to_coord.to_sym; end
+ def from_coord_sym; from_coord && from_coord.to_sym; end
+ def to_coord_sym; to_coord && to_coord.to_sym; end
+
def captured_piece_coord_sym
@captured_piece_coord_sym = captured_piece_coord && captured_piece_coord.to_sym
end
@@ -31,28 +34,18 @@ def before_validation
@piece_moved_upon = @board[to_coord]
end
- # Turns start at one and encompasss two moves each
- def turn
- @turn ||= (self.match.moves.index( self ) + 2) / 2
- end
-
#fields like the notation and whether this was a castling are stored with the move
def update_computed_fields
- # enpassant TODO rewrite
- # if @board.en_passant_capture?( from_coord, to_coord )
- # self.captured_piece_coord = to_coord.gsub( /3/, '4' ).gsub( /6/, '5' )
- # end
-
- #castling
self.castled = 1 if (@piece_moving.function==:king && from_coord_sym.file=='e' && to_coord_sym.file =~ /[cg]/ )
- #finally ensure move is (re)notated
self.notation = notate
+ # self.player = match.opponent_of( match.send( match.next_to_move ) )
end
#stuff here depends on knowledge of the board's position prior to the move being committed
# this should be considered a before-save function and maybe validate is not exactly the best place
def validate
+ return true if self.id # saved moves are valid by definition
if from_coord.blank? && @possible_movers && @possible_movers.length > 1
errors.add :notation, "Ambiguous move #{notation}. Clarify as in Ngf3 or R2d4, for example"
@@ -77,15 +70,11 @@ def validate
end
#can not leave your king in check at end of a move
- #new_board= @board.consider_move( Move.new( :from_coord => from_coord, :to_coord => to_coord ) )
- #if new_board.in_check?( @piece_moving.side )
- # errors.add_to_base "Can not place or leave one's own king in check - you may as well resign if you do that !"
- #end
-
- end
+ new_board= @board.consider_move( Move.new( :from_coord => from_coord, :to_coord => to_coord ) )
+ if new_board.in_check?( @piece_moving.side )
+ errors.add_to_base "Can not place or leave one's own king in check - you may as well resign if you do that !"
+ end
- def player
- match.gameplays.send( match.next_to_move )
end
# In the match passed, how long it has been
@@ -103,8 +92,8 @@ def notify_of_move_via_email
# TODO move email blackout interval into configuration
return unless self.time_since_last_move( self.match ) > ChessNotifier::MINIMUM_TIME_BETWEEN_MOVE_NOTIFICATIONS
- mover = match.gameplays[self.side].player
- opponent = match.gameplays[self.side.opposite].player
+ mover = self.player
+ opponent = match.opponent_of(mover)
ChessNotifier.deliver_opponent_moved(opponent, mover, self)
rescue Exception => ex
$stderr.puts ex.inspect
View
2  app/views/move/_create.html.erb
@@ -18,5 +18,5 @@
<%= javascript_tag("$('move_notation').focus()") %>
<div id="move_error">
- <%= flash[:move_error] %>
+ <%= flash[:error] %>
</div>
View
1  db/schema.rb
@@ -47,6 +47,7 @@
create_table "moves", :force => true do |t|
t.integer "match_id"
+ t.integer "player_id"
t.string "from_coord", :limit => 10
t.string "to_coord", :limit => 10
t.string "notation", :limit => 10
View
12 doc/stats.txt
@@ -2,15 +2,11 @@
+----------------------+-------+-------+---------+---------+-----+-------+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
-| Controllers | 241 | 142 | 6 | 20 | 3 | 5 |
+| Controllers | 225 | 141 | 6 | 21 | 3 | 4 |
| Helpers | 62 | 47 | 0 | 7 | 0 | 4 |
-| Models | 844 | 544 | 18 | 84 | 4 | 4 |
-| Functional tests | 127 | 90 | 2 | 16 | 8 | 3 |
-| Model specs | 685 | 508 | 0 | 0 | 0 | 0 |
-| Controller specs | 281 | 208 | 0 | 0 | 0 | 0 |
-| Helper specs | 9 | 7 | 0 | 0 | 0 | 0 |
+| Models | 844 | 551 | 18 | 83 | 4 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
-| Total | 2249 | 1546 | 26 | 127 | 4 | 10 |
+| Total | 1131 | 739 | 24 | 111 | 4 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
- Code LOC: 733 Test LOC: 813 Code to Test Ratio: 1:1.1
+ Code LOC: 739 Test LOC: 0 Code to Test Ratio: 1:0.0
View
2  lib/notation.rb
@@ -32,7 +32,7 @@ def infer_coordinates_from_notation
self.from_coord = @possible_movers[0][0].to_s and return if @possible_movers.length == 1
disambiguator = notation[-3,1]
matcher = (disambiguator =~ /[1-8]/) ? Regexp.new( "^.#{disambiguator}$" ) : Regexp.new( "^#{disambiguator}.$" )
- movers = @possible_movers.select { |pos, piece| matcher.match(pos) }
+ movers = @possible_movers.select { |pos, piece| matcher.match(pos.to_s) }
self.from_coord = movers[0][0].to_s and return if movers.length == 1
View
4 lib/request_smarts.rb
@@ -4,6 +4,7 @@
# and to extend the request object with other methods which abstract above all of those.
module RequestSmarts
attr_accessor :session, :cookies, :params
+ attr_accessor :player
# an already logged in player
def player_in_session
@@ -21,6 +22,9 @@ def player_in_cookie
def player
player_in_session || player_in_cookie
end
+ def player= p
+ session[:player_id] = p.id
+ end
# any http request is for only one match
def match
View
3  lib/session_smarts.rb
@@ -1,3 +1,4 @@
module SessionSmarts
-
+ def player; self[:player_id] && Player.find(self[:player_id]) ; end
+ def player= p ; self[:player_id] = p.id ; end
end
View
95 spec/controllers/authentication_controller_spec.rb
@@ -1,95 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-require 'mocha'
-
-describe AuthenticationController do
-
- before(:all) do
- @controller = AuthenticationController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- integrate_views
-
- it 'should render the login page for an unauthorized user' do
- get :index
- response.should be_success
- end
-
- it 'should render the registration page' do
- get :register
- response.should be_success
- end
-
- it 'should render a login page' do
- get :login
- response.should be_success
- end
-
- it 'should display a flash notice if login failed' do
- post :login, { :email => 'xxx@ljskd.com', :security_phrase => 'z' }
- flash[:notice].should_not be_nil
- response.should_not be_redirect
- end
-
- it 'should set the player id on a successful login' do
- post :login, { :email => users(:dean).email, :security_phrase => users(:dean).security_phrase }
- session[:player_id].should == users(:dean).playing_as.id
- end
-
- it 'should redirect to matches index page on successful login' do
- post :login, { :email => users(:dean).email, :security_phrase => users(:dean).security_phrase }
- response.should redirect_to( match_index_url )
- end
-
- it 'should clear the session player id on logout' do
- get :logout, {}, { :player_id => 1 }
- session[:player_id].should be_nil
- end
-
- describe 'cookie-based login persistence via auth_token' do
-
- it 'should set a cookie upon hitting the tag action' do
- get :tag
- response.cookies.to_s.should include('auth_token')
- # todo - why does this not work ?
- # response.cookies[:auth_token].should_not be_nil
- end
-
- it 'should redirect to registration after tagging' do
- get :tag
- response.should redirect_to( :action => 'register' )
- end
-
- it 'should not overwrite an existing cookie'
- it 'should not do tagging for facebook sessions (unless proven harmless)'
-
- end
-
- describe 'registration' do
- before(:each) do
- User.expects(:create).returns(User.new)
- Player.expects(:create).returns(players(:dean))
- #Player.any_instance.stubs(:id).returns(7)
- end
-
- it 'should create a user and player record' do
- post :register, { :player => {:name => 'x'},
- :user=>{:security_phrase => 'xx', :email => 'foo@foo.com'} }
- end
-
- it 'should log a person in' do
- post :register, { :player => {:name => 'x'},
- :user=>{:security_phrase => 'xx', :email => 'foo@foo.com'} }
- session[:player_id].should_not be_nil
- end
-
- it 'should associate their facebook info with a new player' do
- Fbuser.expects(:create).returns()
-
- post :register, { :player => {:name => 'x'}, :fb_sig_user => 2001,
- :user=>{:security_phrase => 'xx', :email => 'foo@foo.com'} }
- end
- end
-
-end
View
28 spec/controllers/match_controller_fb_spec.rb
@@ -1,28 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-#Facebook Tests
-=begin
-describe MatchController do
- include Facebooker::Rails::TestHelpers
-
- before(:all) do
- @controller = MatchController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- it 'should get the matches page from facebook for a known user' do
- lambda{
- facebook_get :index, :fb_sig_user => fbusers(:dean).facebook_user_id
- }.should_not raise_error
- response.should be_success
- assert_template 'match/index'
- end
-
- it 'should redirect to register page for unknown facebook user' do
- facebook_get :index, :fb_sig_user => '0000007'
- response.should be_success
- end
-
-end
-=end
View
78 spec/controllers/match_controller_spec.rb
@@ -1,78 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe MatchController do
-
- integrate_views
-
- before(:all) do
- @controller = MatchController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- it 'should allow POST creation of a match between two player_ids' do
- post :create, {:opponent_id => 3, :opponent_side => 'black'}, {:player_id => players(:dean).id }
-
- match = assigns[:match]
-
- match.should_not be_nil
- response.should redirect_to( :controller => :match, :action => :show, :id => match.id )
- match.player2.should == Player.find(3)
- end
-
- it 'should show a match requested' do
- get :show, {:id => matches(:dean_vs_paul).id}, {:player_id => players(:dean).id }
- assigns[:match].should_not be_nil
- end
-
- it 'should render a form for a new match' do
- get :new, {}, {:player_id => players(:dean).id }
- pending{ assigns[:match].should be_a_new_record }
- end
-
- it 'should populate the start position for a new match if FEN given' do
- post :create, {:opponent_id => 3, :opponent_side => 'black', :start_pos => 'R7/8/8/8/8/8/8/8'}, {:player_id => players(:dean).id }
- assigns[:match].start_pos.should == 'R7/8/8/8/8/8/8/8'
- end
-
- it 'should create moves for a new match if PGN given' do
- post :create, {:opponent_id => 3, :opponent_side => 'black', :start_pos => '1. e4'}, {:player_id => players(:dean).id }
- assigns[:match].moves.count.should == 1
- assigns[:match].moves[0].notation.should == 'e4'
- end
-
- it 'should allow resignation via POST' do
- post :resign , {:id => matches(:dean_vs_paul).id}, {:player_id => players(:dean).id }
- assigns[:match].should_not be_active
- end
-
- it 'should show any current move queue in the page' do
- #TODO default the format to html not fbml !
- get :show, {:id => matches(:dean_vs_paul).id, :format => 'html'}, {:player_id => players(:dean).id }
-
- #TODO get this so the proxy returns the unique (first) gameplay per scope
-
- response.should have_tag("div#this_move_queue", :text => 'Nc4 b5')
- end
-
- describe '- status updating' do
- before(:all) do
- end
-
- # /match/5/status?move=8, white queries if the 8th move has been made by black yet
- it 'should detect that the client does not need updating if it sends current value of move param' do
- @match = matches(:castled) #paul white, dean black, dean to move
- get :status, { :id => @match.id, :move => @match.moves.length + 1 }, { :player_id => players(:paul).id }
- assigns(:status_has_changed).should be_false
- end
-
- # /match/5/status?move=8, black queries if the status has changed for move 7
- it 'should detect that the client needs updating if it sends old value of move param' do
- @match = matches(:castled)
- get :status, { :id => @match.id, :move => (@match.moves.length) }, { :player_id => players(:dean).id }
- assigns(:status_has_changed).should be_true
- end
-
- end
-
-end
View
68 spec/controllers/move_controller_spec.rb
@@ -1,68 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe MoveController do
-
- before(:all) do
- @controller = MoveController.new
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- end
-
- it 'should have a flash error upon an invalid move' do
- post :create, {:match_id => matches(:dean_vs_paul).id, :move => { :from_coord =>'e2', :to_coord => 'x9' } }, {:player_id => 1}
- flash[:move_error].should include('x9 is not a valid')
-
- end
-
- it 'should accept a move via coordinates' do
- m = matches(:paul_vs_dean)
-
- post :create, { :match_id => m.id, :move => {:from_coord => 'a2', :to_coord => 'a4'} }, {:player_id => m.player1.id}
- assert_response 302
- assert_nil flash[:move_error]
-
- assert_equal 1, m.reload.moves.length
- assert_not_nil m.moves.last.notation
- end
-
- it 'should accept a move via notation' do
- m = matches(:paul_vs_dean)
- post :create, { :match_id => m.id, :notation => 'a4' }, {:player_id => m.player1.id}
- assert_response 302
- end
-
- it 'should accept a move via ajax' do
- m = matches(:paul_vs_dean)
- xhr :post, :create, { :match_id => m.id, :notation => 'a4' }, {:player_id => m.player1.id}
- response.should be_success
- end
-
- it 'should prohibit moving on a match you dont own' do
- m = matches(:paul_vs_dean)
- lambda{
- post :create, { :match_id => m.id, :move => {:from_coord => 'e2', :to_coord => 'e4'} }, {:player_id => players(:maria).id }
- }.should raise_error
- end
-
- it 'should prohibit moving when not your turn' do
- m = matches(:paul_vs_dean)
- post :create, { :match_id => m.id, :move => {:from_coord=>'e2', :to_coord=>'e4'} }, {:player_id => players(:dean).id }
- flash[:move_error].should_not be_nil
- end
-
- it 'should end the game when a checkmating move posted' do
- m = matches(:scholars_mate)
-
- post :create, { :match_id => m.id, :move => { :notation => 'Qf7' } }, {:player_id => players(:dean).id }
-
- m.reload.winning_player.should_not be_nil
- m.active.should == 0
- end
-
- it 'should redirect to match page (for non ajax move)' do
- m = matches(:paul_vs_dean)
- post :create, { :match_id => m.id, :move => {:from_coord => 'e2', :to_coord => 'e4'} }, {:player_id => players(:paul).id }
- assert_response :redirect
- end
-
-end
View
14 spec/controllers/sets_controller_spec.rb
@@ -1,14 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe SetsController do
-
- controller_name 'sets'
-
- it 'should let you change set' do
- request.env['HTTP_REFERER'] = 'match'
- get :change, :set => 'foo'
- session[:set].should == 'foo'
- response.should be_redirect
- end
-
-end
View
9 spec/helpers/sets_helper_spec.rb
@@ -1,9 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe SetsHelper do
- include SetsHelper
-
- it 'should enumerate sets' do
- available_sets.should include('default')
- end
-end
View
120 spec/lib/fen_spec.rb
@@ -1,120 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe 'Forsyth-Edwards (FEN) Notation' do
-
- INITIAL_BOARD = 'RNBQKBNR/PPPPPPPP/8/8/8/8/pppppppp/rnbqkbnr'
- D4 = 'RNBQKBNR/PPP1PPPP/8/3P4/8/8/pppppppp/rnbqkbnr b'
- D4E4 = 'RNBQKBNR/PPP1PPPP/8/3P4/3p4/8/ppp1pppp/rnbqkbnr'
- ROOK_A1_ONLY = 'R7/8/8/8/8/8/8/8'
- KQ_ONLY = '3KQ3/8/8/8/8/8/8/3kq3'
-
- describe '- in general' do
- it 'should be a module extending Board' do
- b = Board.new
- b.extended_by.should include(Fen)
- end
-
- it 'should allow a board to be created from a Fen string' do
- b = Board.new( INITIAL_BOARD )
- b.should_not be_nil
- b.pieces.should have(32).pieces
- end
-
- it 'should allow a board to be serialized as a Fen string' do
- b = Board.new( Match.new, Chess.initial_pieces )
- b.to_fen.should include( INITIAL_BOARD )
- end
- end
-
- describe '- section layout' do
-
- it 'should have at least three fields separated by whitespace'
-
- it 'should have nothing but piece characters and digits 1-8 and slash in first field'
-
- it 'should have a single w or b in the second field for the side next to move'
-
- it 'should have a dash, or some combination of k and q in the third field'
-
- it 'should optionally have an en passant capture square in the fourth field'
-
- describe '- a section one layout instruction' do
- it 'should correspond to square a1 initially' do
- b = Board.new( ROOK_A1_ONLY )
- b["a1"].function.should == :rook
- end
-
- it 'should lay out a piece if rnbqkp' do
- b = Board.new( ROOK_A1_ONLY )
- b.pieces.should have(1).piece
- end
-
- it 'should lay out a black piece if lower case' do
- b = Board.new( ROOK_A1_ONLY.downcase )
- b["a1"].side.should == :black
- end
-
- it 'should lay out a white piece if upper case' do
- b = Board.new( ROOK_A1_ONLY )
- b["a1"].side.should == :white
- end
-
- it 'should lay out a space if a digit 1-8' do
- b = Board.new( KQ_ONLY )
- b["a1"].should be_nil
- end
-
- it 'should increment by one if a piece was laid out' do
- b = Board.new( KQ_ONLY )
- b["d1"].should_not be_nil
- b["e1"].should_not be_nil
- end
-
- it 'should increment by the number if a number was used' do
- b = Board.new( KQ_ONLY )
- KQ_ONLY[0..0].should == "3"
- ( b["a1"] && b["b1"] && b["c1"] ).should be_nil
-
- end
-
- it 'should increment to the next rank once 8 has been reached' do
- b = Board.new( "8/P7/8/8/8/8/8/8" )
- b.pieces.should have(1).piece
- end
-
- it 'should round-trip quite nicely' do
- b = Board.new( KQ_ONLY )
- b.to_fen.should == KQ_ONLY
- end
- end
-
- describe '- the next to move instruction' do
- it 'should leave white as the next to move if w or nothing in field 2'
-
- it 'should leave black as the next to move if b in field 2'
- end
-
- end
-
- describe '- is in error if' do
- it 'does not account for every square'
-
- it 'over-allocates pieces to the board'
-
- it 'does not place a king'
-
- it 'impossibly places a pawn'
-
- it 'places the player next to move in check'
-
- it 'does not indicate w or b in second field for the next player to move'
-
- it 'indicates an impossible en passant square'
- end
-
- describe '- example boards' do
- it "should recognize #{INITIAL_BOARD} as the initial board"
-
- end
-
-end
View
32 spec/lib/notation_spec.rb
@@ -1,32 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe 'Notation' do
-
- it 'should notate king K' do
- King.new.notation.upcase.should == 'K'
- end
- it 'should notate queen Q' do
- Queen.new.notation.upcase.should == 'Q'
- end
- it 'should notate rook R' do
- Rook.new.notation.upcase.should == 'R'
- end
- it 'should notate knight N' do
- Knight.new.notation.upcase.should == 'N'
- end
- it 'should notate bishop B' do
- Bishop.new.notation.upcase.should == 'B'
- end
-
- it 'should notate a pawn for the file it is on' do
- p = Pawn.new(:black)
- p.notation('b').should == 'b'
- p.notation('c').should == 'c'
- end
-
- it 'should not notate a pawn without its file' do
- p = Pawn.new
- lambda{ p.notation.should == 'p' }.should raise_error
- end
-
-end
View
87 spec/lib/pgn_spec.rb
@@ -1,87 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper.rb'
-
-
-describe Pgn do
- WITH_TAGS = <<EOF
-[Event "F/S Return Match"]
-[Site "Belgrade, Serbia JUG"]
-[Date "1992.11.04"]
-[Round "29"]
-[White "Fischer, Robert J."]
-[Black "Spassky, Boris V."]
-[Result "1/2-1/2"]
-
-1. e4 e5 2. Nf3 Nc6 3. Bb5 a6
-4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8 10. d4 Nbd7
-
-EOF
-
- EVEN_MOVES = "1. e4 e5 2. Nc3 Nf6"
- ODD_MOVES = "1. e4\te5 \n2. Nc3"
-
- before(:all) do
- end
-
- it 'should detect tags in beginning' do
- pgn = Pgn.new(WITH_TAGS)
- pgn.tags.should_not be_empty
- pgn[:round].should == "29"
- end
-
- it 'should detect an even number of moves' do
- pgn = Pgn.new(PgnExamples::EVEN_MOVES)
- pgn.notations.length.should == 4
- pgn.notations[0].should == 'e4'
- pgn.notations[1].should == 'e5'
- pgn.notations[2].should == 'Nc3'
- pgn.notations[3].should == 'Nf6'
- end
-
- it 'should detect an odd number of moves' do
- pgn = Pgn.new(PgnExamples::ODD_MOVES)
- pgn.notations.length.should == 3
- pgn.notations[0].should == 'e4'
- pgn.notations[1].should == 'e5'
- pgn.notations[2].should == 'Nc3'
- end
-
- it 'should scan in spite of comments' do
- pgn = Pgn.new(PgnExamples::WITH_COMMENTS)
- pgn.notations.length.should == 20
- end
-
- it 'should know that a FEN is not a Pgn' do
- Pgn.is_pgn?( 'RNBQKBNR/PPPP1PPP/4P3/8/8/8/pppppppp/rnbqkbnr b' ).should be_false
- end
-
- it 'should know an invalid Pgn when it sees one' do
- pgn = Pgn.new( 'ooga booga' )
- pgn.should_not be_valid
- end
-
- # an integration test unless match stuff is stubbed..
- it 'should be able to playback Pgn against a match' do
- Board.any_instance.stubs('in_check?').returns false
-
- m = matches(:unstarted_match)
- pgn = Pgn.new('1. e4 e5')
- pgn.playback_against(m)
-
- pgn.playback_errors.should be_blank
- m.moves.length.should == 2
- end
-
- it 'should save playback errors' do
- Board.any_instance.stubs('in_check?').returns false
-
- m = matches(:unstarted_match)
- pgn = Pgn.new('1. e4 e5 2. Nd7')
- pgn.playback_against(m)
-
- m.reload.moves.length.should == 2
-
- m.moves.first.notation.should == 'e4'
-
- pgn.playback_errors.should_not be_blank
- end
-end
View
157 spec/models/board_spec.rb
@@ -1,157 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe Board do
-
- it 'should know a valid position by notation' do
- assert Chess.valid_position?('a1')
- assert ! Chess.valid_position?('n9')
- assert ! Chess.valid_position?('a9')
- assert ! Chess.valid_position?('1a')
- end
-
- it 'a pawn on its home square can move one or two' do
- match = matches(:unstarted_match)
- board = match.board
-
- pawn = board[:d2] #TODO we must do away with string access
- Pawn.should === pawn
- pawn.allowed_move?([0,1], 2).should == true
- pawn.allowed_move?([0,2], 2).should == true
-
- pawn.allowed_moves(board).should == [:d3, :d4]
- end
-
- it 'a bishop can not move if it is obstructed' do
- match = matches(:unstarted_match)
- board = match.board
- bishop = board[:c1]
- bishop.allowed_moves(board).should == []
- end
-
- it 'scholars mate capture with queen should be checkmate' do
- Board.any_instance.stubs(:'in_check?').returns(true) # '
-
- match = matches(:scholars_mate)
- match.board['f3'].function.should == :queen
-
- #make the killer move
- match.moves << killer = Move.new( :notation => 'Qf7' )
-
- #king is in check
- RubyProf.start
- match.board.in_check?(:black).should be_true
-
- result = RubyProf.stop
-
- # Print a flat profile to text
- printer = RubyProf::FlatPrinter.new(result)
- #printer.print(STDOUT, 0)
-
- # and it's over !!
- match.board.in_checkmate?(:black).should be_true
- end
-
- it 'scholars mate capture with bishop should not be checkmate' do
- Board.any_instance.stubs(:'in_check?').returns(false) # '
- match = matches(:scholars_mate)
- match.moves << Move.new( :notation => 'Bxf7' )
- match.board.in_check?(:black).should be_false
-
- match.board['e8'].allowed_moves(match.board).should include(:e7)
-
- match.board.should_not be_in_checkmate( :black )
- end
-
- it 'should have no available en_passant sqaure to begin with' do
- match = matches(:unstarted_match)
- match.board.en_passant_square.should be_nil
- end
-
- it 'should record the en_passant square once a pawn has made that move' do
- match = matches(:unstarted_match)
- match.moves << Move.new(:from_coord => 'e2', :to_coord => 'e4')
- match.board.en_passant_square.should == 'e3'
- end
-
- it 'should allow pawn to capture en passant' do
- match = matches(:unstarted_match)
-
- match.moves << Move.new(:notation => 'e4')
- match.moves << Move.new(:notation => 'a5')
- match.moves << Move.new(:notation => 'e5')
- match.moves << Move.new(:notation => 'd5')
-
- board = match.board
-
- board.en_passant_square.to_sym.should == :d6
-
- board[:e5].allowed_moves(board).should include(:d6, :e6)
-
- assert board.en_passant_capture?( 'e5', 'd6' )
-
- match.moves << Move.new(:from_coord => 'e5', :to_coord => 'd6')
-
- assert_equal 'd5', match.moves.last.captured_piece_coord
- assert_nil match.board['d5']
- end
-
- it 'en_passant should not be possible for single stepped opponent pawn' do
- m = matches(:unstarted_match)
- m.moves << Move.new(:notation => 'e4') << Move.new(:notation => 'd6')
- m.moves << Move.new(:notation => 'e5') << Move.new(:notation => 'd5')
-
- b = m.board
- b[:e5].allowed_moves(b).should_not include(:e5)
- end
-
- #LEFTOFF restoring promotion
- it 'should promote automatically to queen' do
-
- m = matches(:promote_crazy)
- puts "\n"+m.board.to_s
- m.moves << promo = Move.new( :from_coord => 'b7', :to_coord => 'a8' )
- promo.should be_valid
-
- puts m.board.to_s
- m.moves.last.notation.should == 'bxa8=Q'
- m.board[:a8].function.should == :queen
- end
-
- it 'can promote to knight' do
- m = matches(:promote_crazy)
- m.moves << Move.new( :from_coord => 'b7', :to_coord => 'a8', :promotion_choice => 'N' )
- pending 'foo'
- end
-
- # consider yields a copy of the board on which the move has occurred
- it 'should considering_a_move_is_temporary' do
- match = matches(:unstarted_match)
- board = match.board
- board['a2'].side.should == :white
- board['e7'].side.should == :black
-
- board.consider_move( Move.new( :from_coord => 'a2', :to_coord => 'a4' ) ) do |new_board|
- new_board['a2'].should be_nil
- new_board['a4'].should_not be_nil
- end
-
- board['a2'].should_not be_nil
- board['a4'].should be_nil
- end
-
- it 'can output board in string format' do
- match = matches(:unstarted_match)
- board = match.board
- board.to_s.should == <<-DaBoard
-r n b q k b n r
-p p p p p p p p
-
-
-
-
-P P P P P P P P
-R N B Q K B N R
-
-DaBoard
- end
-end
View
17 spec/models/chess_notifier_spec.rb
@@ -1,17 +0,0 @@
-require 'spec/spec_helper'
-
-describe ChessNotifier do
- before(:each) do
- ActionMailer::Base.deliveries.clear
- end
-
- it 'should create an opponent_moved email when told' do
- ChessNotifier.deliver_opponent_moved( players(:dean), players(:paul), matches(:dean_vs_paul).moves.last)
- ActionMailer::Base.deliveries.length.should >= 1
- end
-
- it 'should create an match_created email when told' do
- ChessNotifier.deliver_match_created( players(:dean), players(:paul), matches(:dean_vs_paul) )
- ActionMailer::Base.deliveries.length.should >= 1
- end
-end
View
14 spec/models/fbuser_spec.rb
@@ -1,14 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe "Facebook User" do
-
- it "can update name" do
- fb = Fbuser.find_by_facebook_user_id( fbusers(:dean).facebook_user_id )
-
- fb.name = expected = 'Deanoxyz'
-
- fb.reload.playing_as.name.should == expected
- fb.name.should == expected
- end
-
-end
View
25 spec/models/gameplay_spec.rb
@@ -1,25 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe Gameplay do
-
- it "should link a player to a match" do
- with matches(:dean_vs_paul).gameplays do |gps|
- gps.white.player.should == players(:dean)
- gps.black.player.should == players(:paul)
- end
- end
-
- # it "should link a maximum of two players to a match"
-
- it "should be able to store a move queue for a player (low-level)" do
- with matches(:dean_vs_paul).gameplays[0] do |gp|
- gp[:move_queue].should_not be_nil
- end
- end
-
- it "should return a move queue object for a player" do
- with matches(:dean_vs_paul).gameplays[0] do |gp|
- gp.move_queue.should_not be_nil
- end
- end
-end
View
72 spec/models/match_spec.rb
@@ -1,72 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe Match do
-
- it 'should know which side and player is next to move' do
- m1 = matches(:paul_vs_dean)
- m1.next_to_move.should == :white
- m1.current_player.should == players(:paul)
- end
-
- it 'should display the lineup as white vs. black' do
- matches(:paul_vs_dean).lineup.should == 'Paul vs. Dean'
- matches(:dean_vs_paul).lineup.should == 'Dean vs. Paul'
- end
-
- it 'should be startable with one player as white and another as black' do
- m = Match.start( :players => [players(:maria), players(:paul)] )
- m.player2.should == players(:paul)
- end
-
- it 'should have a name' do
- m = matches(:immortal)
- m.name.should == "The Immortal Match (Anderssen vs. Kieseritzky, 1851)"
- end
-
- describe 'resignation' do
-
- it 'should make a match inactive' do
- m1 = matches(:paul_vs_dean)
- m1.resign( players(:paul) )
- m1.should_not be_active
- end
-
- it 'should make the other guy the winner' do
- m1 = matches(:paul_vs_dean)
- m1.resign( players(:paul) )
- m1.winning_player.should == players(:dean)
- end
-
- end
-
- describe "- with FEN changes - " do
-
- AFTER_E4 = 'RNBQKBNR/PPPP1PPP/4P3/8/8/8/pppppppp/rnbqkbnr b'
-
- it 'should have next_to_move black if FEN starts black (and even # of moves)' do
- m = Match.new( :start_pos => AFTER_E4, :players => [players(:dean), players(:paul)] )
- m.next_to_move.should == :black
- end
-
- it 'should have newly retrieved matches current with FEN' do
- m = matches(:e4)
- m.next_to_move.should == :black
- end
-
- it 'should have next_to_move white if FEN starts black (and odd # of moves)' do
- m = matches(:e4)
- m.next_to_move.should == :black
-
- m.moves << newm = Move.new( :from_coord => 'e7', :to_coord => 'e5' )
- m.next_to_move.should == :white
- end
-
- it 'should reflect the piece location FEN indicates, not the initial board' do
- m = matches(:e4)
- m.board['e2'].should be_nil
- m.board['e4'].should_not be_nil
- end
- end
-
-end
-
View
191 spec/models/move_spec.rb
@@ -1,191 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe Move do
-
- it 'should notate a noncapturing knight move' do
- match = matches(:unstarted_match)
- match.moves << Move.new( :from_coord => 'b1', :to_coord => 'c3' )
- assert_equal 'Nc3', match.moves.last.notation
- end
-
- it 'should notates_noncapturing_pawn_moves_correctly' do
- match = matches(:unstarted_match)
- match.moves << Move.new( :from_coord => 'd2', :to_coord => 'd4' ) #queens pawn
- assert_equal 'd4', match.moves.last.notation
-
- match.moves << Move.new( :from_coord => 'e7', :to_coord => 'e5' )
- assert_equal 'e5', match.moves.last.notation
-
- match.moves << Move.new( :from_coord => 'd4', :to_coord => 'e5' )
- assert_equal 'dxe5', match.moves.last.notation
- end
-
- it 'should notates_white_kingside_castle_correctly' do
- match = matches(:dean_vs_maria)
- match.moves << Move.new( :from_coord => 'e1', :to_coord => 'g1' )
-
- assert_equal 1, match.moves.last.castled
- assert_equal 'O-O', match.moves.last.notation
-
- end
-
- it 'should notates_white_queenside_castle_correctly' do
- match = matches(:queenside_castled)
- match.moves << Move.new( :from_coord => 'e1', :to_coord => 'c1' )
- assert_equal 1, match.moves.last.castled
- assert_equal 'O-O-O', match.moves.last.notation
- end
-
- it 'should notates_check_if_no_intervening_piece_blocks_check' do
- match = matches(:dean_vs_paul)
- match.moves << Move.new( :from_coord => 'f8', :to_coord => 'b4' )
- assert_equal 'Bb4+', match.moves.last.notation
- end
-
- it 'should not_notate_check_if_intervening_piece_blocks_check' do
- match = matches(:dean_vs_paul)
- match.moves << Move.new( :from_coord => 'f1', :to_coord => 'b5' )
- assert_equal 'Bb5', match.moves.last.notation
- end
-
- it 'should allow a2b2 style notation' do
- match = matches(:dean_vs_paul)
- match.moves << Move.new( :notation => 'f1b5' )
-
- assert_equal 'f1', match.moves.last.from_coord
- assert_equal 'b5', match.moves.last.to_coord
- end
-
- it 'should allow_move_from_notation_only' do
- match = matches(:dean_vs_paul)
- match.moves << Move.new( :notation => 'Bb5' )
-
- assert_equal 'f1', match.moves.last.from_coord
- assert_equal 'b5', match.moves.last.to_coord
- end
-
- it 'should allow_move_from_notation_only_pawn_version' do
- match = matches(:dean_vs_paul)
- match.moves << Move.new( :notation => 'a4' )
-
- assert_equal 'a2', match.moves.last.from_coord
- assert_equal 'a4', match.moves.last.to_coord
- end
-
- it 'should detect_attempt_to_move_from_incorrect_notation' do
- match = matches(:dean_vs_paul)
-
- #models can raise errors, controllers ultimately should not
- assert_raises ActiveRecord::RecordInvalid do
- match.moves << Move.new( :notation => 'Bb3' )
- end
- end
-
- it 'should detect an illegal move' do
- match = matches(:unstarted_match)
- m = nil
- assert_raises ActiveRecord::RecordInvalid do
- match.moves << m = Move.new( :from_coord => 'b1', :to_coord => 'd1' ) #Nd1 ??
- # match.moves << m = Move.new( :from_coord => 'b3', :to_coord => 'b4' ) # ??
- end
- end
-
- it 'should notate_which_knight_moved_to_a_square_if_ambiguous' do
- match = matches(:queenside_castled)
-
- #there are two knights which could have moved here - did we show which one
- match.moves << Move.new( :from_coord => 'g1', :to_coord => 'f3' )
- assert_equal 'Ngf3', match.moves.last.notation
- end
-
- it 'should disambiguate_knight_move_in_coordinates_when_moved_by_notation' do
- match = matches(:queenside_castled)
- match.moves << move = Move.new( :notation => 'Ngf3' )
- match.moves.last.from_coord.should == 'g1'
- end
-
- it 'should allow castle_via_notation' do
- match = matches(:dean_vs_maria)
- move = match.moves << Move.new( :notation => 'O-O' )
- assert_equal 1, match.moves.last.castled
- assert_equal 'g1', match.moves.last.to_coord
- end
-
- it 'should err if_unrecognized_notation' do
- match = matches(:dean_vs_maria)
- assert_raises ActiveRecord::RecordInvalid do
- match.moves << move = Move.new( :notation => 'move it baby' )
- end
- end
-
- it 'should err_if_ambiguous_move_made_by_notation' do
-
- match = matches(:queenside_castled)
- assert_raises ActiveRecord::RecordInvalid do
- match.moves << move = Move.new( :notation => 'Nf3' )
- end
- end
-
- it 'should disallow combined notation and coordinate move' do
- match = matches(:unstarted_match)
- lambda{
- m = Move.new( :notation => 'e4', :from_coord => 'e2', :to_coord => 'e4' )
- }.should raise_error
-
- end
-
- it 'should be an error to leave ones king in check' do
- match = matches(:scholars_mate)
-
- #this is not a mating move but king is in check and must move
- match.moves << move = Move.new( :notation => 'Bxf7' )
-
- assert_raises ActiveRecord::RecordInvalid do
- match.moves << move = Move.new( :notation => 'Nf6' )
- end
- end
-
- it 'should strip off the move queue part of any notated move' do
- match = matches(:unstarted_match)
- match.moves << m = Move.new( :notation => 'e4 e5 d4' )
- m.notation.should == 'e4'
- end
-
- it 'should store the move queue part of any notated move' do
- match = matches(:unstarted_match)
- match.moves << m = Move.new( :notation => 'e4 e5 d4' )
- m.match.gameplays.white.move_queue.to_s.should == 'e5 d4'
- end
-
- it 'should play the next move in the move queue if the notation matches' do
- match = matches(:unstarted_match)
- match.moves << m = Move.new( :notation => 'e4 e5 d4 Nc6 Nc3' )
- match.moves << m = Move.new( :notation => 'e5' )
-
- match.reload
- match.moves.count.should == 3
- match.moves.reload.last.notation.should == 'd4'
- end
-
- it 'should keep playing from each move queue in turn' do
- match = matches(:unstarted_match)
- match.moves << m = Move.new( :notation => 'e4 e5 d4 Nc6 Nc3' )
- match.moves << m = Move.new( :notation => 'e5 d4 Nc6' )
-
- match.reload ; match.moves.reload
- match.moves[1].notation.should == 'e5'
- match.moves[2].notation.should == 'd4'
- match.moves[3].notation.should == 'Nc6'
- match.moves[4].notation.should == 'Nc3'
-
- match.gameplays.white.move_queue.should be_blank
- end
-
- it 'should invalidate the move queue if an invalid prediction was made' do
- match = matches(:unstarted_match)
- match.moves << m = Move.new( :notation => 'e4 e5 d4 Nc3 Nc6' )
- match.moves << m = Move.new( :notation => 'd5' )
- match.gameplays.white.move_queue.should be_blank
- end
-
-end
View
87 spec/models/piece_spec.rb
@@ -1,87 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe 'Piece' do
-
- it 'should have an image name made of function and color' do
- Rook.new(:black, :queens).img_name.should == 'rook_b'
- Piece.new(:white, :pawn, :c).img_name.should == 'pawn_w'
- end
-
- it 'should have a board id made of function and color and discriminator' do
- Piece.new(:white, :pawn, :c).board_id.should == 'c_pawn_w'
- Rook.new(:black, :queens).board_id.should == 'q_rook_b'
- end
-
- describe 'Move Directions' do
- it 'king can move one in any direction' do
- King.allowed_move?( [0,1] ).should be_true
- end
-
- it 'king can not move more than one in any direction' do
- King.allowed_move?( [0,2] ).should be_false
- end
-
- it 'king can not move more than one in any direction (instance version)' do
- k = King.new(:white)
- k.allowed_move?( [0,2] ).should be_false
- end
-
- it 'queen can move one in any direction' do
- Queen.allowed_move?( [1,0] ).should be_true
- end
-
- it 'queen can move in long straight lines' do
- Queen.allowed_move?( [3,3] ).should be_true
- end
-
- it 'queen cant move like knight' do
- q = Queen.new(:black)
- Queen.allowed_move?( [2,-1] ).should be_false
- end
-
- end
-
- describe 'Piece Types' do
- it 'white pawn can move forward two from its home rank' do
- p = Pawn.new(:white)
- p.allowed_move?( [0, 2], 2).should be_true
- end
-
- it 'white pawn can not move forward two beyond its home rank' do
- p = Pawn.new(:white)
- p.allowed_move?( [0, 2], 4).should be_false
- end
-
- it 'white pawn can move forward-diagonal one unit' do
- p = Pawn.new(:white)
- p.allowed_move?( [1, 1], 2).should be_true
- end
-
- it 'black pawn can move forward two from its home rank' do
- p = Pawn.new(:black)
- p.allowed_move?( [0, -2], 7).should be_true
- end
-
- it 'white pawn can not move forward two beyond its home rank' do
- p = Pawn.new(:white)
- p.allowed_move?( [0, -2], 5).should be_false
- end
-
- it 'knight can move 2 and 1 units' do
- k = Knight.new(:black)
- k.allowed_move?( [1, -2] ).should be_true
- end
- end
-
- describe 'Allowed move examples' do
- it 'should count bishops moves after 1. e4 correctly' do
- Board.any_instance.stubs('in_checkmate?').returns false
- Board.any_instance.stubs('in_check?').returns false
-
- m = matches(:unstarted_match)
- m.moves << Move.new(:from_coord => 'e2', :to_coord => 'e4')
-
- m.board[:f1].allowed_moves(m.board).should == [:e2, :d3, :c4, :b5, :a6]
- end
- end
-end
View
30 spec/models/player_spec.rb
@@ -1,30 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe Player do
-
- it "can be created" do
- p = Player.new
- p.should_not be_nil
- end
-
- it "has a name" do
- p = Player.new :name => "Deano"
- p.name.should == "Deano"
- end
-
- it "should not be allowed to register an existing name" do
- p = Player.new :name => players(:dean).name
- p.should_not be_valid
- end
-
- it "should retrieve matches for a player" do
- p = Player.find(1)
- p.matches.count.should > 1
- end
-
- it "should retrieve active matches for a player" do
- p = Player.find(1)
- p.matches.active.count.should > 1
- end
-
-end
View
67 spec/models/promotion.rb
@@ -1,67 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe 'Piece' do
-
- it 'should recognize_valid_piece_types' do
- p = Piece.new(:white, :queens_knight)
- p = Piece.new(:black, :a_pawn)
- #completes without error
- end
-
- it 'should image_names_abstract_away_irrelevant_details' do
- assert_equal 'rook_b', Rook.new(:black, :queens).img_name
- assert_equal 'pawn_w', Piece.new(:white, :pawn, :c).img_name
- end
-
- it 'board_id should combine all fields' do
- Piece.new(:white, :pawn, :c).board_id.should == 'c_pawn_w'
- Rook.new(:black, :queens).board_id.should == 'q_rook_b'
- end
-
- it 'should nodoc_piece_is_promotable_to_queen_by_default' do
- p = Piece.new(:white, :b_pawn)
- p.promote!('8')
-
- assert_equal :queen.to_s, p.role
- end
-
- it 'should pawn_may_not_promote_to_king' do
- p = Piece.new(:black, :c_pawn)
- assert_raises ArgumentError do
- p.promote!('8', :king )
- end
- end
-
- it 'should pawn_may_not_promote_unless_on_back_rank' do
- #black pawn must be on 1
- p = Piece.new(:black, :c_pawn)
- assert_raises ArgumentError do
- p.promote!('8')
- end
-
- p.side = :white
- assert_raises ArgumentError do
- p.promote!('7')
- end
- end
-
- it 'should nodoc_ascertains_promotability' do
- p = Piece.new(:black, :c_pawn)
- assert ! p.promotable?('8')
- assert Piece.new(:black, :f_pawn).promotable?('1')
- end
-
- it 'should nodoc_board_id_indicates_promoted_piece' do
- p = Piece.new(:white, :a_pawn)
- p.promote!('8')
- assert_equal 'white_promoted_queen', p.board_id
- end
-
- it 'should no_piece_other_than_pawn_may_promote' do
- p = Piece.new(:black, :queens_bishop)
- assert_raises ArgumentError do
- p.promote!('8')
- end
- end
-
-end
View
18 spec/models/user_spec.rb
@@ -1,18 +0,0 @@
-require File.dirname(__FILE__) + '/../spec_helper'
-
-describe 'User model' do
-
- it 'should point to a player' do
- u1 = User.find_by_email "chicagogrooves@gmail.com"
-
- u1.playing_as.should be_kind_of Player
- u1.playing_as.name.should == "Dean"
- u1.playing_as.id.should == 1
- end
-
- #it 'should be creatable with the suggested player name' do
- # u = User.create_with_player( {:email => 'foo@foo.com', :security_phrase => 'x'}, {:name => 'myoplex'} )
- # u.should_not be_nil
- # u.playing_as.name.should == 'myoplex'
- #end
-end
View
4 spec/spec_helper.rb
@@ -13,8 +13,8 @@
config.use_transactional_fixtures = true
config.use_instantiated_fixtures = false
- config.fixture_path = RAILS_ROOT + '/test/fixtures/'
- config.global_fixtures = :all # :matches, :players, :moves, :users, :fbusers
+ config.fixture_path = Dir.join(RAILS_ROOT, 'test/fixtures')
+ config.global_fixtures = :all
# == Mock Framework
#
View
58 test/functional/fbuser_controller_test.rb
@@ -1,58 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class FbuserControllerTest < ActionController::TestCase
-
- def test_can_sniff_facebook_request_test_or_actual
-
- get :index, { :fb_sig_user => fbusers(:dean).facebook_user_id }
- assert_equal fbusers(:dean).facebook_user_id, session[:facebook_user_id]
- assert_equal players(:dean).id , session[:player_id]
-
- end
-
- def test_does_not_authenticate_without_facebook_info
- get :index, { :fb_sig_user => '' }
-
- assert_nil session[:facebook_user_id]
- assert_nil assigns[:current_player]
- end
-
- def test_redirected_to_login_to_facebook_when_requested_in_TEST_environment_and_unauthenticated
- get :index
- assert_response 302
- assert_equal true, @response.redirected_to.include?( 'facebook.com/login' )
- end
-
- def test_known_fbuser_can_invoke_register_to_set_new_name
- post :register, { :name => 'New name', :fb_sig_user => fbusers(:dean).facebook_user_id }
- assert_response 302
- assert_equal 'New name', fbusers(:dean).reload.name
- end
-
- def test_unknown_fbuser_can_invoke_register_to_establish_self_with_new_name
- unknown_id = fbusers(:dean).facebook_user_id + 1
-
- assert_nil Fbuser.find_by_facebook_user_id( unknown_id )
-
- post :register, { :name => 'Newer name', :fb_sig_user => unknown_id }
-
- #now we have them
- assert_not_nil fbuser = Fbuser.find_by_facebook_user_id( unknown_id )
-
- #have recorded their name
- assert_equal 'Newer name', fbuser.name
-
- #and sent them on their way
- assert_response 302
- end
-
- def test_newly_registered_user_gets_a_match_with_me
- unknown_id = fbusers(:dean).facebook_user_id + 1
-
- assert_nil Fbuser.find_by_facebook_user_id( unknown_id )
-
- get :index , { :fb_sig_user => unknown_id }
- post :register, { :name => 'Newer name', :fb_sig_user => unknown_id }
- assert_equal 1, Fbuser.find_by_facebook_user_id( unknown_id ).playing_as.active_matches.count
- end
-end
View
69 test/functional/match_controller_test.rb
@@ -1,69 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class MatchControllerTest < ActionController::TestCase
-
- # TODO this will change if viewing a read-only match
- def test_redirected_to_login_if_requesting_active_match
- get :show, { :id => matches(:paul_vs_dean).id } #no player_id in session
- assert_response 302
- end
-
- def test_redirected_to_match_listing_page_when_resigning_match
- get :resign, { :format => 'html', :id => 2}, {:player_id => 1}
- assert_response 302
- end
-
- def test_white_view_of_board_when_requested_by_white
- get :show, { :id => matches(:paul_vs_dean).id }, {:player_id => players(:paul).id }
- assert_response 200
- assert_equal :white, assigns['viewed_from_side']
-
- #assert 8 is first in the list so when board rendered down page, 1 is at the bottom
- assert_equal '8', assigns['ranks'][0].chr
- end
-
- def test_black_view_of_board_when_requested_by_black
- get :show, { :id => matches(:paul_vs_dean).id }, {:player_id => players(:dean).id }
-
- assert_response 200
- assert_equal :black, assigns['viewed_from_side']
-
- assert_equal '1', assigns['ranks'][0].chr
- end
-
- def test_requesting_ended_match_yields_result_template
- get :show, { :id => matches(:resigned).id }, {:player_id => players(:dean).id }
- assert_response 200
- assert_template 'match/result'
- end
-
- def test_gets_form_for_creating_new_match
- get :new, nil, {:player_id => players(:dean).id }
- assert_response 200
- assert_template 'match/new'
- end
-
- def test_creates_new_match_opponent_as_black
- post :create, {:opponent_side => 2, :opponent_id => players(:paul).id}, {:player_id => players(:dean).id }
- assert_not_nil assigns['match']
- assert_response 302
- end
-
- def test_gets_match_status
- get :status, { :id => matches(:paul_vs_dean).id}, {:player_id => players(:paul).id }
- assert_response 200
- end
-
- def test_gets_list_of_active_matches
- get :index, nil, {:player_id => players(:paul).id }
- assert_equal [], assigns['matches'].find { |m| m.id == matches(:resigned).id }
- assert_response 200
- end
-
- def test_verifies_showing_a_match_renders_the_board
- get :show, { :id => 9 }, {:player_id => players(:dean).id }
- assert_response 200
- assert_select 'table#board_table'
- end
-
-end
Please sign in to comment.
Something went wrong with that request. Please try again.