Integrate role asset studio into custom world agent flow
This commit is contained in:
131
src/components/AdventurePanel.test.tsx
Normal file
131
src/components/AdventurePanel.test.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { AdventurePanel } from './AdventurePanel';
|
||||
import { AnimationState, type Character, type StoryMoment, type StoryOption, WorldType } from '../types';
|
||||
|
||||
function createCharacter(): Character {
|
||||
return {
|
||||
id: 'hero',
|
||||
name: '沈行',
|
||||
title: '试剑客',
|
||||
description: '测试主角',
|
||||
backstory: '测试背景',
|
||||
avatar: '/hero.png',
|
||||
portrait: '/hero.png',
|
||||
assetFolder: 'hero',
|
||||
assetVariant: 'default',
|
||||
attributes: {
|
||||
strength: 10,
|
||||
agility: 10,
|
||||
intelligence: 8,
|
||||
spirit: 9,
|
||||
},
|
||||
personality: 'calm',
|
||||
skills: [],
|
||||
adventureOpenings: {},
|
||||
} as Character;
|
||||
}
|
||||
|
||||
function createOption(functionId: string, actionText: string): StoryOption {
|
||||
return {
|
||||
functionId,
|
||||
actionText,
|
||||
text: actionText,
|
||||
visuals: {
|
||||
playerAnimation: AnimationState.IDLE,
|
||||
playerMoveMeters: 0,
|
||||
playerOffsetY: 0,
|
||||
playerFacing: 'right',
|
||||
scrollWorld: false,
|
||||
monsterChanges: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function renderPanel(currentStory: StoryMoment, displayedOptions: StoryOption[]) {
|
||||
return renderToStaticMarkup(
|
||||
<AdventurePanel
|
||||
aiError={null}
|
||||
currentStory={currentStory}
|
||||
isLoading={false}
|
||||
displayedOptions={displayedOptions}
|
||||
hideOptions={false}
|
||||
canRefreshOptions={false}
|
||||
onRefreshOptions={() => undefined}
|
||||
onChoice={() => undefined}
|
||||
onOpenCharacter={() => undefined}
|
||||
onOpenInventory={() => undefined}
|
||||
playerCharacter={createCharacter()}
|
||||
worldType={WorldType.WUXIA}
|
||||
quests={[]}
|
||||
questUi={{
|
||||
acknowledgeQuestCompletion: () => undefined,
|
||||
claimQuestReward: () => null,
|
||||
}}
|
||||
goalStack={{
|
||||
northStarGoal: null,
|
||||
activeGoal: null,
|
||||
immediateStepGoal: null,
|
||||
supportGoals: [],
|
||||
}}
|
||||
goalPulse={null}
|
||||
onDismissGoalPulse={() => undefined}
|
||||
battleRewardUi={{
|
||||
reward: null,
|
||||
dismiss: () => undefined,
|
||||
}}
|
||||
playerHp={100}
|
||||
playerMaxHp={100}
|
||||
playerMana={20}
|
||||
playerMaxMana={20}
|
||||
playerSkillCooldowns={{}}
|
||||
inBattle={false}
|
||||
currentNpcBattleMode={null}
|
||||
statistics={{
|
||||
playTimeMs: 0,
|
||||
hostileNpcsDefeated: 0,
|
||||
questsAccepted: 0,
|
||||
questsCompleted: 0,
|
||||
questsTurnedIn: 0,
|
||||
itemsUsed: 0,
|
||||
scenesTraveled: 0,
|
||||
currentSceneName: '竹林古道',
|
||||
playerCurrency: 0,
|
||||
inventoryItemCount: 0,
|
||||
inventoryStackCount: 0,
|
||||
activeCompanionCount: 0,
|
||||
rosterCompanionCount: 0,
|
||||
}}
|
||||
musicVolume={0.6}
|
||||
onMusicVolumeChange={() => undefined}
|
||||
onSaveAndExit={() => undefined}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
test('adventure panel recognizes story_continue_adventure by function id instead of action text', () => {
|
||||
const continueOption = createOption('story_continue_adventure', '查看后续');
|
||||
const currentStory: StoryMoment = {
|
||||
text: '你们交换完这一轮判断。',
|
||||
options: [continueOption],
|
||||
deferredOptions: [createOption('idle_explore_forward', '继续向前探索')],
|
||||
};
|
||||
|
||||
const html = renderPanel(currentStory, [continueOption]);
|
||||
|
||||
expect(html).toContain('剧情推理完成,继续后显示新的冒险选项');
|
||||
});
|
||||
|
||||
test('adventure panel does not show deferred hint for non-continue options with the same text', () => {
|
||||
const misleadingOption = createOption('npc_chat', '查看后续');
|
||||
const currentStory: StoryMoment = {
|
||||
text: '你们交换完这一轮判断。',
|
||||
options: [misleadingOption],
|
||||
deferredOptions: [createOption('idle_explore_forward', '继续向前探索')],
|
||||
};
|
||||
|
||||
const html = renderPanel(currentStory, [misleadingOption]);
|
||||
|
||||
expect(html).not.toContain('剧情推理完成,继续后显示新的冒险选项');
|
||||
});
|
||||
Reference in New Issue
Block a user