Files
pikachu/test/base/PikachuBaseTest.js
2025-07-17 14:16:06 +07:00

180 lines
6.3 KiB
JavaScript

import { PikachuGameLogic } from '../../src/game/logic/PikachuGameLogic.js';
/**
* Base test class for Pikachu game pattern testing
*/
export class PikachuBaseTest {
constructor() {
this.game = new PikachuGameLogic();
}
/**
* Create an empty board matrix with border padding
* @returns {number[][]} Empty matrix
*/
createEmptyMatrix() {
const matrix = [];
for (let row = 0; row < this.game.matrixHeight; row++) {
matrix[row] = [];
for (let col = 0; col < this.game.matrixWidth; col++) {
matrix[row][col] = 0;
}
}
return matrix;
}
/**
* Place a card on the board matrix
* @param {number[][]} matrix - The board matrix
* @param {number} row - Row position (1-indexed for game board)
* @param {number} col - Column position (1-indexed for game board)
* @param {number} cardType - Card type (positive number)
* @returns {number[][]} Modified matrix
*/
placeCard(matrix, row, col, cardType) {
if (row < 1 || row > this.game.boardHeight || col < 1 || col > this.game.boardWidth) {
throw new Error(`Position (${row}, ${col}) is out of bounds`);
}
matrix[row][col] = cardType;
return matrix;
}
/**
* Create a test case with expected result
* @param {string} name - Test case name
* @param {number[][]} matrix - Board matrix
* @param {number} row1 - First card row
* @param {number} col1 - First card column
* @param {number} row2 - Second card row
* @param {number} col2 - Second card column
* @param {boolean} expected - Expected result
* @param {string} expectedPattern - Expected pattern type
* @param {string} expectedError - Expected error message (for invalid moves)
* @returns {Object} Test case object
*/
createTestCase(name, matrix, row1, col1, row2, col2, expected, expectedPattern = null, expectedError = null) {
return {
name,
matrix,
row1,
col1,
row2,
col2,
expected,
expectedPattern,
expectedError
};
}
/**
* Run a single test case
* @param {Object} testCase - Test case object
* @returns {Object} Test result
*/
runTestCase(testCase) {
// Load the board
this.game.loadBoardFromMatrix(testCase.matrix);
// Test the move
const result = this.game.testMove(testCase.row1, testCase.col1, testCase.row2, testCase.col2);
// Check if result matches expectation
const passed = result.valid === testCase.expected;
const patternMatch = !testCase.expectedPattern || result.details?.pattern === testCase.expectedPattern;
return {
name: testCase.name,
passed: passed && patternMatch,
expected: testCase.expected,
actual: result.valid,
expectedPattern: testCase.expectedPattern,
actualPattern: result.details?.pattern || 'none',
error: result.error,
details: result.details
};
}
/**
* Execute a test case with Jest expectations
* @param {Object} testCase - Test case object
*/
expectTestCase(testCase) {
// Load the board
this.game.loadBoardFromMatrix(testCase.matrix);
// Test the move
const result = this.game.testMove(testCase.row1, testCase.col1, testCase.row2, testCase.col2);
// Jest assertions
if (testCase.expected) {
expect(result).toBeValidMove();
if (testCase.expectedPattern) {
expect(result).toHavePattern(testCase.expectedPattern);
}
} else {
expect(result.valid).toBe(false);
if (testCase.expectedError) {
expect(result.error).toContain(testCase.expectedError);
}
}
}
/**
* Assert that a move is valid with specific pattern
* @param {number[][]} matrix - Board matrix
* @param {number} row1 - First card row
* @param {number} col1 - First card column
* @param {number} row2 - Second card row
* @param {number} col2 - Second card column
* @param {string} expectedPattern - Expected pattern type
*/
assertValidMove(matrix, row1, col1, row2, col2, expectedPattern) {
this.game.loadBoardFromMatrix(matrix);
const result = this.game.testMove(row1, col1, row2, col2);
if (!result.valid) {
throw new Error(`Expected valid move but got: ${result.error}`);
}
if (expectedPattern && result.details.pattern !== expectedPattern) {
throw new Error(`Expected pattern ${expectedPattern} but got ${result.details.pattern}`);
}
}
/**
* Assert that a move is invalid
* @param {number[][]} matrix - Board matrix
* @param {number} row1 - First card row
* @param {number} col1 - First card column
* @param {number} row2 - Second card row
* @param {number} col2 - Second card column
* @param {string} expectedError - Expected error message (optional)
*/
assertInvalidMove(matrix, row1, col1, row2, col2, expectedError = null) {
this.game.loadBoardFromMatrix(matrix);
const result = this.game.testMove(row1, col1, row2, col2);
if (result.valid) {
throw new Error(`Expected invalid move but got valid move with pattern: ${result.details.pattern}`);
}
if (expectedError && !result.error.includes(expectedError)) {
throw new Error(`Expected error containing "${expectedError}" but got: ${result.error}`);
}
}
/**
* Print board matrix for debugging
* @param {number[][]} matrix - Board matrix
*/
printBoard(matrix) {
console.log('\nBoard state:');
console.log(' ', Array.from({length: this.game.matrixWidth}, (_, i) => i.toString().padStart(2)).join(' '));
for (let row = 0; row < this.game.matrixHeight; row++) {
const rowStr = matrix[row].map(cell => cell.toString().padStart(2)).join(' ');
console.log(`${row.toString().padStart(2)}: ${rowStr}`);
}
console.log();
}
}