90 lines
2.2 KiB
TypeScript
90 lines
2.2 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { render, screen } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { afterEach, expect, test, vi } from 'vitest';
|
|
|
|
import { AnimationState, type Character } from '../types';
|
|
import {
|
|
CharacterIdentityBadges,
|
|
CharacterSkillsList,
|
|
PlayerLevelProgress,
|
|
} from './CharacterInfoShared';
|
|
|
|
function createSkill(
|
|
name: string,
|
|
style: Character['skills'][number]['style'],
|
|
): Character['skills'][number] {
|
|
return {
|
|
id: '',
|
|
name,
|
|
animation: AnimationState.IDLE,
|
|
damage: 12,
|
|
manaCost: 4,
|
|
cooldownTurns: 2,
|
|
range: 1,
|
|
style,
|
|
};
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
test('CharacterSkillsList falls back to stable render ids when skill ids are empty', async () => {
|
|
const user = userEvent.setup();
|
|
const handleSelectSkill = vi.fn();
|
|
const consoleErrorSpy = vi
|
|
.spyOn(console, 'error')
|
|
.mockImplementation(() => undefined);
|
|
|
|
render(
|
|
<CharacterSkillsList
|
|
skills={[
|
|
createSkill('潮刃突进', 'burst'),
|
|
createSkill('雾行转位', 'mobility'),
|
|
]}
|
|
onSelectSkill={handleSelectSkill}
|
|
/>,
|
|
);
|
|
|
|
const buttons = screen.getAllByRole('button');
|
|
await user.click(buttons[0]!);
|
|
await user.click(buttons[1]!);
|
|
|
|
expect(handleSelectSkill).toHaveBeenNthCalledWith(1, 'skill-潮刃突进-0');
|
|
expect(handleSelectSkill).toHaveBeenNthCalledWith(2, 'skill-雾行转位-1');
|
|
|
|
const duplicateKeyCalls = consoleErrorSpy.mock.calls.filter((call) =>
|
|
call.some(
|
|
(arg) =>
|
|
typeof arg === 'string' &&
|
|
arg.includes('Encountered two children with the same key'),
|
|
),
|
|
);
|
|
|
|
expect(duplicateKeyCalls).toHaveLength(0);
|
|
});
|
|
|
|
test('CharacterIdentityBadges renders role and level chips together', () => {
|
|
render(
|
|
<CharacterIdentityBadges
|
|
roleLabel="队长"
|
|
roleTone="amber"
|
|
levelText="Lv.7"
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByText('队长')).toBeTruthy();
|
|
expect(screen.getByText('Lv.7')).toBeTruthy();
|
|
});
|
|
|
|
test('PlayerLevelProgress renders xp progress details', () => {
|
|
render(
|
|
<PlayerLevelProgress level={6} currentLevelXp={72} xpToNextLevel={120} />,
|
|
);
|
|
|
|
expect(screen.getByText('Lv.6')).toBeTruthy();
|
|
expect(screen.getByText('72/120')).toBeTruthy();
|
|
});
|