draughtsboard
Version:
draughtsboard, checkersboard implementation in javascript
451 lines (361 loc) • 17.8 kB
JavaScript
describe('Board Interaction Tests', function() {
beforeEach(function() {
$('#test-boards').empty();
});
afterEach(function() {
$('#test-boards .test-board').each(function() {
const $board = $(this);
if($board.data('board') && $board.data('board').destroy) {
$board.data('board').destroy();
}
});
$('#test-boards').empty();
});
describe('Drag and Drop Functionality', function() {
it('should initialize draggable pieces when draggable is true', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start'
});
expect(board).to.be.an('object');
// Check that pieces are draggable by looking for drag-related classes/attributes
const $pieces = $container.find('.square-55d63:not(:empty)');
expect($pieces.length).to.be.greaterThan(0);
$container.data('board', board);
});
it('should not allow dragging when draggable is false', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: false,
position: 'start'
});
expect(board).to.be.an('object');
$container.data('board', board);
});
it('should handle drag constraints by color', function() {
let dragAttempts = [];
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: function(source, piece, position, orientation) {
dragAttempts.push({ source, piece, position, orientation });
// Only allow white pieces to be dragged
return piece.search(/^w/) !== -1;
},
position: 'start',
onDragStart: function(source, piece, position, orientation) {
expect(source).to.be.a('string');
expect(piece).to.be.a('string');
expect(piece.search(/^w/)).to.not.equal(-1); // Should only be white pieces
}
});
expect(board).to.be.an('object');
$container.data('board', board);
});
it('should trigger onDragStart event with correct parameters', function() {
let dragStartEvents = [];
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start',
onDragStart: function(source, piece, position, orientation) {
dragStartEvents.push({
source: source,
piece: piece,
position: position,
orientation: orientation
});
expect(source).to.be.a('string');
expect(piece).to.be.a('string');
expect(['w', 'b', 'W', 'B']).to.include(piece);
expect(position).to.be.an('object');
expect(['white', 'black']).to.include(orientation);
}
});
expect(board).to.be.an('object');
$container.data('board', board);
});
it('should handle onDrop events with validation', function() {
let dropEvents = [];
let moveAccepted = false;
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: { '6': 'w', '31': 'b' },
onDrop: function(source, target, piece, newPos, oldPos, orientation) {
dropEvents.push({
source: source,
target: target,
piece: piece,
newPos: newPos,
oldPos: oldPos,
orientation: orientation
});
expect(source).to.be.a('string');
expect(target).to.be.a('string');
expect(piece).to.be.a('string');
expect(newPos).to.be.an('object');
expect(oldPos).to.be.an('object');
expect(['white', 'black']).to.include(orientation);
// Simple validation - allow moves to empty squares
if (!oldPos[target]) {
moveAccepted = true;
return 'snapback';
}
return 'snapback';
}
});
expect(board).to.be.an('object');
$container.data('board', board);
});
it('should handle snapback animation on invalid moves', function(done) {
let snapbackCount = 0;
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: { '6': 'w' },
snapbackSpeed: 'fast',
onDrop: function() {
return 'snapback'; // Always snapback for test
},
onSnapbackEnd: function(source, square, position, orientation) {
snapbackCount++;
expect(source).to.be.a('string');
expect(square).to.be.a('string');
expect(position).to.be.an('object');
expect(['white', 'black']).to.include(orientation);
if (snapbackCount === 1) {
done();
}
}
});
expect(board).to.be.an('object');
$container.data('board', board);
// Note: Actually triggering snapback would require DOM event simulation
// For now, we're testing the configuration setup
setTimeout(() => {
if (snapbackCount === 0) {
done(); // Complete test even if no snapback was triggered
}
}, 1000);
});
it('should handle different drop-off-board behaviors', function() {
const behaviors = ['snapback', 'trash'];
behaviors.forEach(behavior => {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: { '6': 'w' },
dropOffBoard: behavior
});
expect(board).to.be.an('object');
if(board && board.destroy) {
board.destroy();
}
$container.remove();
});
});
});
describe('Mouse Events', function() {
it('should trigger onMouseoverSquare and onMouseoutSquare events', function() {
let mouseoverEvents = [];
let mouseoutEvents = [];
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
position: 'start',
onMouseoverSquare: function(square, piece) {
mouseoverEvents.push({ square, piece });
expect(square).to.be.a('string');
// piece can be false for empty squares
},
onMouseoutSquare: function(square, piece) {
mouseoutEvents.push({ square, piece });
expect(square).to.be.a('string');
// piece can be false for empty squares
}
});
expect(board).to.be.an('object');
// Simulate mouse events
const $squares = $container.find('.square-55d63');
expect($squares.length).to.be.greaterThan(0);
// Test that event handlers are properly set up
// Note: Actual DOM event triggering would require more complex setup
$container.data('board', board);
});
it('should provide correct square information in mouse events', function() {
let eventSquares = [];
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
position: { '1': 'w', '25': 'b', '50': 'W' },
onMouseoverSquare: function(square, piece) {
eventSquares.push({ square, piece });
// Validate square number
const squareNum = parseInt(square, 10);
expect(squareNum).to.be.within(1, 50);
// If there's a piece, validate its type
if (piece) {
expect(['w', 'b', 'W', 'B']).to.include(piece);
}
}
});
expect(board).to.be.an('object');
$container.data('board', board);
});
});
describe('Piece Selection and Highlighting', function() {
it('should handle piece selection states', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
position: 'start',
draggable: true
});
expect(board).to.be.an('object');
// Check that squares can have selection/highlight classes
const $squares = $container.find('.square-55d63');
expect($squares.length).to.be.greaterThan(0);
$container.data('board', board);
});
it('should handle square highlighting programmatically', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
position: 'start'
});
expect(board).to.be.an('object');
// Test manual highlighting if board supports it
// (This would depend on the actual implementation having highlight methods)
$container.data('board', board);
});
});
describe('Touch and Mobile Support', function() {
it('should handle touch events for mobile devices', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start',
onDragStart: function() {
// Should work for both mouse and touch
},
onDrop: function() {
return 'snapback';
}
});
expect(board).to.be.an('object');
// Check that touch events are properly bound
// Note: Actual touch event testing would require more sophisticated setup
$container.data('board', board);
});
it('should maintain responsiveness on different screen sizes', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
$container.css({ width: '300px', height: '300px' });
const board = DraughtsBoard($container[0], {
position: 'start'
});
expect(board).to.be.an('object');
// Test resizing
$container.css({ width: '500px', height: '500px' });
board.resize();
// Board should still function after resize
expect(board.position()).to.be.an('object');
$container.data('board', board);
});
});
describe('Keyboard Support', function() {
it('should handle keyboard navigation if supported', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
position: 'start'
});
expect(board).to.be.an('object');
// Note: Keyboard support would depend on implementation
// This test verifies the board doesn't break with focus events
$container.data('board', board);
});
});
describe('Performance and Memory', function() {
it('should handle rapid interaction without memory leaks', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
let eventCount = 0;
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start',
onChange: function() {
eventCount++;
}
});
expect(board).to.be.an('object');
// Simulate rapid position changes
for(let i = 0; i < 10; i++) {
board.position({ [(i + 1).toString()]: 'w' });
}
expect(eventCount).to.be.greaterThan(0);
$container.data('board', board);
});
it('should clean up event listeners on destroy', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start',
onDragStart: function() {},
onDrop: function() { return 'snapback'; },
onMouseoverSquare: function() {},
onMouseoutSquare: function() {}
});
expect(board).to.be.an('object');
// Destroy the board
board.destroy();
// Container should be cleaned up
expect($container.find('.board-b72b1')).to.have.length(0);
});
});
describe('Edge Cases and Error Handling', function() {
it('should handle rapid drag operations gracefully', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start',
onDrop: function() {
// Randomly accept or reject moves
return Math.random() > 0.5 ? 'snapback' : null;
}
});
expect(board).to.be.an('object');
// Board should remain stable
expect(board.position()).to.be.an('object');
$container.data('board', board);
});
it('should handle invalid drop targets', function() {
let invalidDrops = 0;
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: { '6': 'w' },
onDrop: function(source, target, piece) {
// Validate that target is a valid square
const targetNum = parseInt(target, 10);
if (isNaN(targetNum) || targetNum < 1 || targetNum > 50) {
invalidDrops++;
}
return 'snapback';
}
});
expect(board).to.be.an('object');
$container.data('board', board);
});
it('should maintain state consistency during interactions', function() {
const $container = $('<div class="test-board">').appendTo('#test-boards');
const board = DraughtsBoard($container[0], {
draggable: true,
position: 'start',
onDrop: function(source, target, piece, newPos, oldPos) {
// Verify position consistency
expect(oldPos[source]).to.equal(piece);
expect(newPos[target]).to.equal(piece);
expect(newPos[source]).to.be.undefined;
return 'snapback'; // Always snapback for consistency
}
});
expect(board).to.be.an('object');
$container.data('board', board);
});
});
});