| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import { describe, it, expect, vi } from 'vitest';
- import { Item, BallItem, LineClearItem } from '../src/entities/Item.js';
- import { GRID_GAP, ITEM_SIZE_RATIO } from '../src/constants.js';
- describe('Item (base class)', () => {
- describe('constructor', () => {
- it('initializes with correct properties', () => {
- const item = new Item(3, 2, 'ball', 40);
- expect(item.gridX).toBe(3);
- expect(item.gridY).toBe(2);
- expect(item.type).toBe('ball');
- expect(item.size).toBe(40);
- expect(item.collected).toBe(false);
- });
- });
- describe('getRect()', () => {
- it('converts grid coordinates to pixel coordinates with reduced size', () => {
- const size = 40;
- const item = new Item(2, 3, 'ball', size);
- const rect = item.getRect();
- const itemSize = size * ITEM_SIZE_RATIO;
- const offset = (size - itemSize) / 2;
- expect(rect.x).toBe(2 * (size + GRID_GAP) + GRID_GAP + offset);
- expect(rect.y).toBe(3 * (size + GRID_GAP) + GRID_GAP + offset);
- expect(rect.width).toBe(itemSize);
- expect(rect.height).toBe(itemSize);
- });
- it('returns correct rect for origin (0,0)', () => {
- const size = 50;
- const item = new Item(0, 0, 'ball', size);
- const rect = item.getRect();
- const itemSize = size * ITEM_SIZE_RATIO;
- const offset = (size - itemSize) / 2;
- expect(rect.x).toBe(GRID_GAP + offset);
- expect(rect.y).toBe(GRID_GAP + offset);
- expect(rect.width).toBe(itemSize);
- expect(rect.height).toBe(itemSize);
- });
- });
- describe('shouldRemove()', () => {
- it('returns false by default', () => {
- const item = new Item(0, 0, 'ball', 40);
- expect(item.shouldRemove()).toBe(false);
- });
- });
- describe('moveDown()', () => {
- it('increments gridY by 1', () => {
- const item = new Item(3, 2, 'ball', 40);
- item.moveDown();
- expect(item.gridY).toBe(3);
- });
- });
- });
- describe('BallItem', () => {
- describe('constructor', () => {
- it('initializes with type "ball"', () => {
- const item = new BallItem(1, 2, 40);
- expect(item.type).toBe('ball');
- expect(item.gridX).toBe(1);
- expect(item.gridY).toBe(2);
- expect(item.collected).toBe(false);
- });
- });
- describe('onCollect()', () => {
- it('calls game.addPendingBall() and marks collected', () => {
- const game = { addPendingBall: vi.fn() };
- const item = new BallItem(0, 0, 40);
- item.onCollect(game);
- expect(game.addPendingBall).toHaveBeenCalledOnce();
- expect(item.collected).toBe(true);
- });
- });
- describe('shouldRemove()', () => {
- it('returns true (ball items are removed on collect)', () => {
- const item = new BallItem(0, 0, 40);
- expect(item.shouldRemove()).toBe(true);
- });
- });
- });
- describe('LineClearItem', () => {
- describe('constructor', () => {
- it('initializes with type "lineClear"', () => {
- const item = new LineClearItem(4, 5, 40, 'horizontal');
- expect(item.type).toBe('lineClear');
- expect(item.gridX).toBe(4);
- expect(item.gridY).toBe(5);
- expect(item.collected).toBe(false);
- expect(item.direction).toBe('horizontal');
- });
- });
- describe('onCollect()', () => {
- it('marks collected and calls clearRow for horizontal direction', () => {
- const game = { clearRow: vi.fn(), clearColumn: vi.fn() };
- const item = new LineClearItem(3, 7, 40, 'horizontal');
- item.onCollect(game);
- expect(item.collected).toBe(true);
- expect(game.clearRow).toHaveBeenCalledWith(7);
- expect(game.clearColumn).not.toHaveBeenCalled();
- });
- it('marks collected and calls clearColumn for vertical direction', () => {
- const game = { clearRow: vi.fn(), clearColumn: vi.fn() };
- const item = new LineClearItem(5, 2, 40, 'vertical');
- item.onCollect(game);
- expect(item.collected).toBe(true);
- expect(game.clearColumn).toHaveBeenCalledWith(5);
- expect(game.clearRow).not.toHaveBeenCalled();
- });
- it('triggers clear each time onCollect is called', () => {
- const game = { clearRow: vi.fn(), clearColumn: vi.fn() };
- const item = new LineClearItem(3, 2, 40, 'horizontal');
- item.onCollect(game);
- item.onCollect(game);
- expect(game.clearRow).toHaveBeenCalledTimes(2);
- });
- });
- describe('shouldRemove()', () => {
- it('returns false before collection', () => {
- const item = new LineClearItem(0, 0, 40, 'horizontal');
- expect(item.shouldRemove()).toBe(false);
- });
- it('returns false after collection (stays on board)', () => {
- const game = { clearRow: vi.fn(), clearColumn: vi.fn() };
- const item = new LineClearItem(0, 0, 40, 'horizontal');
- item.onCollect(game);
- expect(item.shouldRemove()).toBe(false);
- });
- });
- });
|