Files
Genarrative/src/services/storyEngine/carrierNarrativeCompiler.test.ts
T
kdletters cbc27bad4a
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

132 lines
4.3 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
type InventoryItem,
type RuntimeItemAiIntent,
type RuntimeItemGenerationContext,
type RuntimeItemPlan,
WorldType,
} from '../../types';
import {
buildCarrierNarrativeDescription,
buildCarrierNarrativeName,
buildRuntimeItemStoryFingerprint,
} from './carrierNarrativeCompiler';
function createContext(): RuntimeItemGenerationContext {
return {
worldType: WorldType.CUSTOM,
customWorldProfile: null,
sceneId: 'scene-1',
sceneName: '断桥旧哨',
sceneDescription: '旧哨火和断桥一起守着边城北口。',
sceneTags: ['断桥', '旧哨火'],
treasureHints: [],
encounter: null,
encounterNpcId: 'npc-1',
encounterNpcName: '梁砺',
encounterContextText: '巡守',
relatedNpcState: null,
relatedNpcNarrativeProfile: {
publicMask: '他只承认自己还在守桥。',
firstContactMask: '先别问旧案,桥口还不能放开。',
visibleLine: '他把全部注意力都压在桥口和来路上。',
hiddenLine: '他真正盯着的是封桥旧令背后的名字。',
contradiction: '嘴上只说守桥,提到名单时却会明显收紧语气。',
debtOrBurden: '封桥那夜的后果还压在他身上。',
taboo: '封桥令',
immediatePressure: '裂潮再逼桥口,他不敢轻易放人过去。',
relatedThreadIds: ['thread-1'],
relatedScarIds: ['scar-1'],
reactionHooks: ['名单', '旧哨火'],
},
relatedScene: {
id: 'scene-1',
name: '断桥旧哨',
description: '旧哨火和断桥一起守着边城北口。',
treasureHints: [],
},
recentStorySummary: '桥口的风声越来越不对。',
recentActions: ['你刚和巡守对上了第一轮试探。'],
activeThreadIds: ['thread-1'],
playerCharacterId: 'hero',
playerBuildTags: ['守御', '追击'],
playerBuildGaps: ['mana_gap'],
playerEquipmentTags: ['weapon'],
generationChannel: 'quest_reward',
};
}
describe('carrierNarrativeCompiler', () => {
it('builds fingerprint, patterned name, and layered description', () => {
const item: InventoryItem = {
id: 'runtime:test-item',
category: '稀有品',
name: '未命名秘物',
quantity: 1,
rarity: 'rare',
tags: ['relic'],
equipmentSlotId: 'relic',
runtimeMetadata: {
origin: 'ai_compiled',
generationChannel: 'quest_reward',
seedKey: 'seed',
sourceReason: '桥口的旧事把它重新推到了你眼前。',
},
};
const plan: RuntimeItemPlan = {
slot: 'primary',
itemKind: 'quest',
permanence: 'permanent',
narrativeWeight: 'heavy',
targetBuildDirection: ['守御', '追击'],
relationAnchor: {
type: 'npc',
npcId: 'npc-1',
npcName: '梁砺',
roleText: '巡守',
},
};
const intent: RuntimeItemAiIntent = {
shortNameSeed: '断桥',
sourcePhrase: '梁砺',
reasonToAppear: '桥口的旧事把它重新推到了你眼前。',
relationHooks: ['旧哨火'],
desiredBuildTags: ['守御', '追击'],
desiredFunctionalBias: ['guard'],
tone: 'ritual',
visibleClue: '桥口旧铜味一直留在它的边角。',
witnessMark: '它曾被人攥着在封桥夜里来回传递。',
unfinishedBusiness: '它为什么会在封桥之后一直没有被交回去?',
hiddenHook: '有人故意让它留在旧哨火旁。',
reactionHooks: ['名单', '封桥令'],
namingPattern: 'forbidden_object',
};
const fingerprint = buildRuntimeItemStoryFingerprint({
context: createContext(),
plan,
intent,
});
const name = buildCarrierNarrativeName({
item,
context: createContext(),
plan,
intent,
});
const description = buildCarrierNarrativeDescription({
item,
context: createContext(),
plan,
intent,
});
expect(fingerprint.visibleClue).toContain('桥口');
expect(name).toContain('封桥令'.slice(0, 2));
expect(name).toContain('封痕');
expect(description).toContain('它和');
expect(description).toContain('如今它会在断桥旧哨出现');
expect(description).toContain('适合当前局势里的临场构筑调整');
});
});