From 3bbbe73b1fc1d8c360fac008388f3c74bf167fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Sun, 31 May 2026 13:40:21 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E6=B7=BB=E5=8A=A0=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E9=80=BB=E8=BE=91=E5=92=8C=E6=A3=8B=E7=9B=98?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- .../board/__tests__/board-renderer.test.ts | 63 +++++++++++++++++++ src/core/__tests__/types.test.ts | 38 +++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/components/board/__tests__/board-renderer.test.ts create mode 100644 src/core/__tests__/types.test.ts diff --git a/src/components/board/__tests__/board-renderer.test.ts b/src/components/board/__tests__/board-renderer.test.ts new file mode 100644 index 0000000..23500b5 --- /dev/null +++ b/src/components/board/__tests__/board-renderer.test.ts @@ -0,0 +1,63 @@ +import { describe, it, expect } from 'vitest'; +import { + computeBoardDimensions, + canvasToBoard, + boardToCanvas, + computeStarPoints, +} from '../board-renderer'; + +describe('computeBoardDimensions', () => { + it('returns positive cellSize and padding for 15x15 board', () => { + const cfg = computeBoardDimensions(15, 800, 600); + expect(cfg.cellSize).toBeGreaterThan(0); + expect(cfg.padding).toBeGreaterThan(0); + expect(cfg.boardSize).toBe(15); + }); + + it('fits within the smaller canvas dimension', () => { + const cfg = computeBoardDimensions(15, 800, 600); + const total = cfg.padding * 2 + (cfg.boardSize - 1) * cfg.cellSize; + expect(total).toBeLessThanOrEqual(800); + }); +}); + +describe('canvasToBoard / boardToCanvas round-trip', () => { + it('round-trips for a 15x15 board center', () => { + const cfg = computeBoardDimensions(15, 800, 600); + const boardPos = { x: 7, y: 7 }; + const canvas = boardToCanvas(boardPos, cfg); + const restored = canvasToBoard(canvas.x, canvas.y, cfg); + expect(restored).toEqual(boardPos); + }); + + it('returns null for clicks outside the board', () => { + const cfg = computeBoardDimensions(15, 800, 600); + expect(canvasToBoard(-10, -10, cfg)).toBeNull(); + expect(canvasToBoard(9999, 9999, cfg)).toBeNull(); + }); +}); + +describe('computeStarPoints', () => { + it('returns 9 star points for 15x15 board', () => { + const points = computeStarPoints(15); + expect(points.length).toBe(9); + }); + + it('returns only center for board smaller than 9', () => { + const points = computeStarPoints(7); + expect(points.length).toBe(1); + expect(points[0]).toEqual([3, 3]); + }); + + it('star points are within board bounds', () => { + for (const size of [9, 13, 15, 19]) { + const points = computeStarPoints(size); + for (const [r, c] of points) { + expect(r).toBeGreaterThanOrEqual(0); + expect(r).toBeLessThan(size); + expect(c).toBeGreaterThanOrEqual(0); + expect(c).toBeLessThan(size); + } + } + }); +}); diff --git a/src/core/__tests__/types.test.ts b/src/core/__tests__/types.test.ts new file mode 100644 index 0000000..1c15884 --- /dev/null +++ b/src/core/__tests__/types.test.ts @@ -0,0 +1,38 @@ +import { describe, it, expect } from 'vitest'; + +describe('types', () => { + it('CellState values are correct', () => { + const empty: number = 0; + const black: number = 1; + const white: number = 2; + expect(empty).toBe(0); + expect(black).toBe(1); + expect(white).toBe(2); + }); + + it('MoveResult has correct shape', () => { + const result = { + position: { x: 7, y: 7 }, + is_win: false, + is_forbidden: false, + }; + expect(result.position.x).toBe(7); + expect(result.is_win).toBe(false); + }); + + it('GameConfig has all required fields with defaults', () => { + const config = { + boardSize: 15, + useForbiddenRules: true, + useTimer: false, + timeLimitSecs: 60, + aiDifficulty: 3, + playerColor: 'Black' as const, + isServer: false, + remoteAddress: '', + }; + expect(config.boardSize).toBeGreaterThanOrEqual(9); + expect(config.boardSize).toBeLessThanOrEqual(19); + expect(['Black', 'White']).toContain(config.playerColor); + }); +});