test/board.test.js
const expect = require('chai').expect;
const Tile = require('../src/battleship/tile');
const Board = require('../src/battleship/board');
const Ship = require('../src/battleship/ship');
const Moves = require('../src/battleship/moves');
const parameters = require('../src/battleship/parameters');
const { numRows, numColumns, shipTypes, orientations, totalCount } = parameters;
/**
* @test {Board}
*/
describe('Board constructor', function() {
const board = new Board();
it('should contain a matrix of tiles', function() {
// const board = new Board();
for (let i = 0; i < numRows; i++) {
for (let j = 0; j < numColumns; j++) {
const tile = board.tiles[i][j];
expect(tile).to.be.an.instanceof(Tile);
}
}
});
it('should be initialized with an empty array for ships', function() {
expect(Array.isArray(board.ships)).to.be.true;
});
it('should be initialized with isSetUp as false', function() {
expect(board.isSetUp).to.be.false;
})
it('should have an instance of Moves', function() {
expect(board.moves).to.be.an.instanceof(Moves);
})
});
/**
* @test {Board}
*/
describe('Board.setup', function() {
it('it should add ships at random positions if setup is called with no parameters',
function(){
const board = new Board();
board.setUp();
expect(board.isSetUp).to.be.true;
expect(board.ships.length).to.equal(totalCount);
}
);
});
/**
* @test {Board}
*/
describe('Board.addShip', function() {
it('should be able to add a ship to the board if the position is valid', function() {
for (let shipTypeId of Object.keys(shipTypes)) {
const { length } = shipTypes[shipTypeId];
for (let orientation of Object.keys(orientations)) {
const { rowFactor, columnFactor } = orientations[orientation];
for (let startRow = 0; startRow < numRows - rowFactor * length; startRow++) {
for (let startColumn = 0; startColumn < numColumns - columnFactor * length; startColumn++) {
const board = new Board();
const ship = new Ship({shipTypeId, orientation, startRow, startColumn});
expect(board.addShip(ship)).to.be.true;
expect(board.ships.includes(ship));
}
}
}
}
});
it('should mark the appropriate tiles after a ship is added', function() {
const board = new Board();
const aircraftCarrier = new Ship({
shipTypeId: 1,
orientation: 'horizontal',
startRow: 3,
startColumn : 3
});
board.addShip(aircraftCarrier);
const tiles = board.tiles[3].slice(3, 5);
tiles.forEach(tile => {
expect(tile.ship).to.equal(aircraftCarrier);
})
});
it('should return false if adding a ship will overlap an existing ship', function() {
const board = new Board();
const aircraftCarrier = new Ship({
shipTypeId: 1,
orientation: 'horizontal',
startRow: 3,
startColumn : 3
});
const battleship = new Ship({
shipTypeId: 2,
orientation: 'vertical',
startRow: 0,
startColumn: 5
});
board.addShip(aircraftCarrier);
expect(board.addShip(battleship)).to.be.false;
});
it('should increment the appropriate shipTypeCount', function() {
const ships = Board.getSampleShipArray();
const board = new Board();
board.setUp(ships);
expect(board.shipTypeCount).to.eql({
1: 1,
2: 1,
3: 1,
4: 2,
5: 2
})
});
it('should return false if the shipTypeCount is exceeded', function() {
const aircraftCarrier1 = new Ship({
shipTypeId: 1,
orientation: 'horizontal',
startRow: 3,
startColumn: 3
});
const aircraftCarrier2 = new Ship({
shipTypeId: 1,
orientation: 'vertical',
startRow: 1,
startColumn: 8
});
const board = new Board();
board.addShip(aircraftCarrier1);
expect(board.addShip(aircraftCarrier2)).to.be.false;
});
it('should have isSetUp set to true after all required ships are added', function() {
const ships = Board.getSampleShipArray();
const board = new Board();
ships.forEach(ship => {
board.addShip(ship);
});
expect(board.isSetUp).to.be.true;
});
it('should have the intial board saved to Moves after all required ships are added', function() {
const ships = Board.getSampleShipArray();
const board = new Board();
ships.forEach(ship => {
board.addShip(ship);
});
expect(board.moves.moves.length).to.equal(1);
expect(board.moves.boardHtml.length).to.equal(1);
expect(board.moves.boardString.length).to.equal(1);
});
});
/**
* @test {Board}
*/
describe('Board.attack', function() {
it('should correctly register an Island', function() {
const board = new Board();
const ships = Board.getSampleShipArray();
console.log('sample ship array', ships);
board.setUp(ships);
const result = board.attack({row: 0, column: 0})
console.log('board.attack(0,0)', result);
// expect(board.attack({row: 0, column: 0})).to.equal('Island');
expect(result).to.equal('Island');
});
it('should correctly register a Hit', function() {
const aircraftCarrier = new Ship({
shipTypeId: 1,
orientation: 'horizontal',
startRow: 3,
startColumn: 3
});
const board = new Board();
board.addShip(aircraftCarrier);
board.setUp();
expect(board.attack({row: 3, column: 3})).to.equal('Hit');
});
it('should correctly register a Miss', function() {
const board = new Board();
const ships = Board.getSampleShipArray();
board.setUp(ships);
expect(board.attack({row: 0, column: 0})).to.equal('Miss');
});
it('should correctly register a Already Attacked', function() {
const board = new Board();
const ships = Board.getSampleShipArray();
board.setUp(ships);
expect(board.attack({row: 0, column: 0})).to.equal('Miss');
expect(board.attack({row: 0, column: 0})).to.equal('Already Attacked');
});
it('should correctly register a Sunk', function() {
const aircraftCarrier = new Ship({
shipTypeId: 1,
orientation: 'horizontal',
startRow: 3,
startColumn: 3
});
const board = new Board();
board.addShip(aircraftCarrier);
board.setUp();
expect(board.attack({row: 3, column: 3})).to.equal('Hit');
expect(board.attack({row: 3, column: 4})).to.equal('Hit');
expect(board.attack({row: 3, column: 5})).to.equal('Hit');
expect(board.attack({row: 3, column: 6})).to.equal('Hit');
expect(board.attack({row: 3, column: 7})).to.equal('Sunk');
});
it('should correctly register a Win', function() {
const board = new Board();
const ships = Board.getSampleShipArray();
board.setUp(ships);
// Aircraft Carrier
expect(board.attack({row: 1, column: 9})).to.equal('Hit');
expect(board.attack({row: 2, column: 9})).to.equal('Hit');
expect(board.attack({row: 3, column: 9})).to.equal('Hit');
expect(board.attack({row: 4, column: 9})).to.equal('Hit');
expect(board.attack({row: 5, column: 9})).to.equal('Sunk');
// Battleship
expect(board.attack({row: 4, column: 7})).to.equal('Hit');
expect(board.attack({row: 5, column: 7})).to.equal('Hit');
expect(board.attack({row: 6, column: 7})).to.equal('Hit');
expect(board.attack({row: 7, column: 7})).to.equal('Sunk');
// Cruiser
expect(board.attack({row: 6, column: 2})).to.equal('Hit');
expect(board.attack({row: 6, column: 3})).to.equal('Hit');
expect(board.attack({row: 6, column: 4})).to.equal('Sunk');
// Destroyer 1
expect(board.attack({row: 1, column: 1})).to.equal('Hit');
expect(board.attack({row: 2, column: 1})).to.equal('Sunk');
// Destroyer 2
expect(board.attack({row: 4, column: 3})).to.equal('Hit');
expect(board.attack({row: 4, column: 4})).to.equal('Sunk');
// Submarine 1
expect(board.attack({row: 2, column: 3})).to.equal('Sunk');
// Submarine 2
expect(board.attack({row: 8, column: 1})).to.equal('Win');
});
});
/**
* @test {Board}
*/
describe('Board.addMove', function() {
it('should be called from Board.attack', function() {
const board = new Board();
board.setUp();
board.attack({row: 0, column: 0});
expect(board.moves.moves.length).to.equal(2);
});
it('should be reset isRandom to false after it is called', function() {
const board = new Board();
board.setUp();
board.moves.setIsRandom(true);
board.attack({row: 0, column: 0});
expect(board.moves.isRandom).to.be.false;
});
});
/**
* @test {Board}
*/
describe('Board.isWon', function() {
it('should return true after all the ships are sunk', function() {
const board = new Board();
const ships = Board.getSampleShipArray();
board.setUp(ships);
// Aircraft Carrier
expect(board.attack({row: 1, column: 9})).to.equal('Hit');
expect(board.attack({row: 2, column: 9})).to.equal('Hit');
expect(board.attack({row: 3, column: 9})).to.equal('Hit');
expect(board.attack({row: 4, column: 9})).to.equal('Hit');
expect(board.attack({row: 5, column: 9})).to.equal('Sunk');
// Battleship
expect(board.attack({row: 4, column: 7})).to.equal('Hit');
expect(board.attack({row: 5, column: 7})).to.equal('Hit');
expect(board.attack({row: 6, column: 7})).to.equal('Hit');
expect(board.attack({row: 7, column: 7})).to.equal('Sunk');
// Cruiser
expect(board.attack({row: 6, column: 2})).to.equal('Hit');
expect(board.attack({row: 6, column: 3})).to.equal('Hit');
expect(board.attack({row: 6, column: 4})).to.equal('Sunk');
// Destroyer 1
expect(board.attack({row: 1, column: 1})).to.equal('Hit');
expect(board.attack({row: 2, column: 1})).to.equal('Sunk');
// Destroyer 2
expect(board.attack({row: 4, column: 3})).to.equal('Hit');
expect(board.attack({row: 4, column: 4})).to.equal('Sunk');
// Submarine 1
expect(board.attack({row: 2, column: 3})).to.equal('Sunk');
// Submarine 2
expect(board.attack({row: 8, column: 1})).to.equal('Win');
// isWon
expect(board.isWon()).to.be.true;
})
});
/**
* @test {Board}
*/
describe('Board.getSampleShipArray', function() {
it('should return an array of length = totalCount', function() {
const ships = Board.getSampleShipArray();
expect(ships.length).to.equal(totalCount);
});
});