TheCorrespondingSquares/chess-app

View on GitHub
spec/models/game_spec.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'rails_helper'

RSpec.describe Game, type: :model do
    let!(:user) { FactoryGirl.create(:user) }
  let(:game) { FactoryGirl.create(:game, white_player_id: user.id)}

  describe '.available' do
      let!(:user2) { FactoryGirl.create(:user) }

    context 'when some games are not available' do
          let!(:game1) { FactoryGirl.create(:game, white_player_id: user.id) }
          let!(:game2) { FactoryGirl.create(:game, black_player_id: user2.id, white_player_id: user.id)}

      it 'show an available game' do
              expect(Game.available.count).to eq 1
      end

          it 'show the last available game' do
              expect(Game.available.last).to eq game1
          end
    end

    context 'when all games are available' do
          let!(:game1) { FactoryGirl.create(:game, white_player_id: user.id)}
          let!(:game2) { FactoryGirl.create(:game, black_player_id: user2.id)}

      it 'show an available game' do
              expect(Game.available.count).to eq 2
      end

            it 'show the last vailable game' do
                expect(Game.available.last).to eq game2
            end
    end

    context 'when all existing games are unavailable' do
          let!(:game1) { FactoryGirl.create(:game, white_player_id: user.id, black_player_id: user2.id)}
          let!(:game2) { FactoryGirl.create(:game, black_player_id: user2.id, white_player_id: user.id)}

          it 'show any game' do
              expect(Game.available.count).to eq 0
          end
    end
  end

  describe "#check?" do
    let(:game) { FactoryGirl.create(:game, white_player_id: user.id)}
    let(:king) { FactoryGirl.create(:king, color: "White", x_pos: 7, y_pos: 7, game_id: game.id) }
    before(:each) { game.pieces.destroy_all }

    context 'when a Rook puts King in check' do
      let!(:piece_making_check) { FactoryGirl.create(:rook, color: "Black", captured: false, x_pos: 7, y_pos: 0, game_id: game.id) }

      it ' should raise an alert' do
        expect(game.check?(king.color)).to eq(true)
      end
    end

    context 'when a Bishop puts King in check' do
      let!(:piece_making_check) { FactoryGirl.create(:bishop, color: "Black", captured: false, x_pos: 0, y_pos: 0, game_id: game.id) }

      it ' should raise an alert' do
        expect(game.check?(king.color)).to eq(true)
      end
    end

    context 'when a piece does not put King in check' do
      let!(:piece_making_check) { FactoryGirl.create(:queen, color: "Black", captured: false, x_pos: 2, y_pos: 3, game_id: game.id) }

      it ' should not raise any alert' do
        expect(game.check?(king.color)).to eq(false)
      end
    end
  end

  describe "#checkmate?" do
    let(:game) { FactoryGirl.create(:game, white_player_id: user.id)}
    let(:king) { FactoryGirl.create(:king, color: "White", x_pos: 7, y_pos: 7, game_id: game.id) }
    before(:each) { game.pieces.destroy_all }  

    context 'when a bishop moves to a checkmate position' do
      let!(:piece_making_check) { FactoryGirl.create(:bishop, color: "Black", captured: false, x_pos: 4, y_pos: 4, game_id: game.id) }
      let!(:pawn) { FactoryGirl.create(:pawn, color: "White", x_pos: 5, y_pos: 4, game_id: game.id) }
      let!(:bishop) { FactoryGirl.create(:bishop, color: "White", x_pos: 7, y_pos: 6, game_id: game.id) }
      let!(:knight) { FactoryGirl.create(:knight, color: "White", x_pos: 6, y_pos: 7, game_id: game.id) }
      it ' the bishop can be blocked ' do
        expect(game.checkmate?(king.color)).to eq(false)
      end  
    end

    context 'when a bishop moves to a checkmate position' do
      let!(:piece_making_check) { FactoryGirl.create(:bishop, color: "Black", captured: false, x_pos: 2, y_pos: 2, game_id: game.id) }
      let!(:bishop) { FactoryGirl.create(:bishop, color: "White", x_pos: 7, y_pos: 6, game_id: game.id) }
      let!(:bishop2) { FactoryGirl.create(:bishop, color: "White", x_pos: 6, y_pos: 7, game_id: game.id) }
      it ' the king cannot capture the bishop' do
        expect(game.checkmate?(king.color)).to eq(true)
      end
    end

    context 'when a bishop moves to a checkmate position' do
      let!(:piece_making_check) { FactoryGirl.create(:bishop, color: "Black", captured: false, x_pos: 6, y_pos: 6, game_id: game.id) }
      it ' the king can capture the bishop' do
        expect(game.checkmate?(king.color)).to eq(false)
      end
    end

    context 'when a bishop moves to a checkmate position' do
      let!(:piece_making_check) { FactoryGirl.create(:bishop, color: "Black", captured: false, x_pos: 0, y_pos: 0, game_id: game.id) }
      let!(:bishop) { FactoryGirl.create(:bishop, color: "White", x_pos: 7, y_pos: 6, game_id: game.id) }
      let!(:bishop2) { FactoryGirl.create(:bishop, color: "White", x_pos: 6, y_pos: 7, game_id: game.id) }
      it ' the king cannot move out of the check position' do
        expect(game.checkmate?(king.color)).to eq(true)
      end
    end

    context 'when a bishop moves to a checkmate position' do
      let!(:piece_making_check) { FactoryGirl.create(:bishop, color: "Black", captured: false, x_pos: 0, y_pos: 0, game_id: game.id) }
      let!(:pawn) { FactoryGirl.create(:pawn, color: "White", x_pos: 7, y_pos: 6, game_id: game.id) }
      it ' the king can move out of the check position' do
        expect(game.checkmate?(king.color)).to eq(false)
      end
    end

  end

  describe "#stalemate?" do
    let(:black_player) { FactoryGirl.create(:user) }
    let(:game_stalemate) { FactoryGirl.create(:game, white_player_id: user.id, black_player_id: black_player.id) } 
    before(:each) { game_stalemate.update_attributes(turn: 43) }
    before(:each) { game_stalemate.pieces.destroy_all }

    it 'if stalemate, should return TRUE and leave game unchanged' do
      black_king = FactoryGirl.create(:king, color: "Black", x_pos: 0, y_pos: 7, game_id: game_stalemate.id)
      black_bishop = FactoryGirl.create(:bishop, color: "Black", x_pos: 1, y_pos: 7, game_id: game_stalemate.id)
      FactoryGirl.create(:king, color: "White", x_pos: 1, y_pos: 5, game_id: game_stalemate.id)
      FactoryGirl.create(:rook, color: "White", x_pos: 7, y_pos: 7, game_id: game_stalemate.id)

      stalemate = game_stalemate.stalemate?("Black")
      game_stalemate.reload
      black_king.reload
      black_bishop.reload

      expect(stalemate).to eq(true)
      expect(game_stalemate.turn).to eq(43)
      expect(black_king.x_pos).to eq(0)
      expect(black_king.y_pos).to eq(7)
      expect(black_bishop.x_pos).to eq(1)
      expect(black_bishop.y_pos).to eq(7)
    end
      
    it 'if no stalemate, should return FALSE and leave game unchanged' do
      black_king = FactoryGirl.create(:king, color: "Black", x_pos: 0, y_pos: 7, game_id: game_stalemate.id)
      black_bishop = FactoryGirl.create(:bishop, color: "Black", x_pos: 1, y_pos: 7, game_id: game_stalemate.id)
      FactoryGirl.create(:king, color: "White", x_pos: 1, y_pos: 5, game_id: game_stalemate.id)
      FactoryGirl.create(:rook, color: "White", x_pos: 7, y_pos: 4, game_id: game_stalemate.id)        
      
      stalemate = game_stalemate.stalemate?("Black")
      game_stalemate.reload
      black_king.reload
      black_bishop.reload

      expect(stalemate).to eq(false)
      expect(game_stalemate.turn).to eq(43)
      expect(black_king.x_pos).to eq(0)
      expect(black_king.y_pos).to eq(7)
      expect(black_bishop.x_pos).to eq(1)
      expect(black_bishop.y_pos).to eq(7)
    end
  end

end