119 lines
3.8 KiB
TypeScript
119 lines
3.8 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { type CustomWorldProfile,WorldType } from '../../types';
|
|
import { buildKnowledgeGraph } from './knowledgeGraph';
|
|
|
|
const profile: CustomWorldProfile = {
|
|
id: 'world-1',
|
|
settingText: '裂潮边城',
|
|
name: '裂潮边城',
|
|
subtitle: '旧案回响',
|
|
summary: '一座在裂潮和旧案之间摇摇欲坠的边城。',
|
|
tone: '紧张、克制、暗流涌动',
|
|
playerGoal: '查清封桥旧令',
|
|
templateWorldType: WorldType.WUXIA,
|
|
majorFactions: ['巡边司'],
|
|
coreConflicts: ['封桥旧案再起'],
|
|
attributeSchema: {
|
|
id: 'schema',
|
|
worldId: 'world-1',
|
|
schemaVersion: 1,
|
|
generatedFrom: {
|
|
worldType: WorldType.CUSTOM,
|
|
worldName: '裂潮边城',
|
|
settingSummary: '裂潮边城',
|
|
tone: '紧张、克制、暗流涌动',
|
|
conflictCore: '封桥旧案再起',
|
|
},
|
|
slots: [],
|
|
},
|
|
playableNpcs: [],
|
|
storyNpcs: [
|
|
{
|
|
id: 'npc-1',
|
|
name: '梁砺',
|
|
title: '断桥巡守',
|
|
role: '巡守',
|
|
description: '守着断桥与旧哨火的巡守。',
|
|
backstory: '旧案爆发时,他是最后一个封桥的人。',
|
|
personality: '警觉直接,不喜欢绕弯。',
|
|
motivation: '不想让旧案再次借裂潮翻上来。',
|
|
combatStyle: '长兵先压,再卡住路口。',
|
|
initialAffinity: 6,
|
|
relationshipHooks: ['封桥', '旧哨火'],
|
|
tags: ['巡守', '断桥'],
|
|
backstoryReveal: {
|
|
publicSummary: '他只承认自己还在守桥。',
|
|
chapters: [
|
|
{
|
|
id: 'surface',
|
|
title: '表层来意',
|
|
affinityRequired: 0,
|
|
teaser: '桥还不能放开。',
|
|
content: '他总先谈桥和路。',
|
|
contextSnippet: '桥还不能放开。',
|
|
},
|
|
],
|
|
},
|
|
skills: [],
|
|
initialItems: [],
|
|
narrativeProfile: {
|
|
publicMask: '他只承认自己还在守桥。',
|
|
firstContactMask: '先别问旧案,桥口还不能放开。',
|
|
visibleLine: '他把全部注意力都压在桥口和来路上。',
|
|
hiddenLine: '他真正盯着的是封桥旧令背后的名字。',
|
|
contradiction: '嘴上只说守桥,提到名单时却会明显收紧语气。',
|
|
debtOrBurden: '封桥那夜的后果还压在他身上。',
|
|
taboo: '封桥令',
|
|
immediatePressure: '裂潮再逼桥口,他不敢轻易放人过去。',
|
|
relatedThreadIds: ['thread-1'],
|
|
relatedScarIds: ['scar-1'],
|
|
reactionHooks: ['名单', '旧哨火'],
|
|
},
|
|
},
|
|
],
|
|
items: [],
|
|
landmarks: [],
|
|
themePack: null,
|
|
storyGraph: {
|
|
visibleThreads: [
|
|
{
|
|
id: 'thread-1',
|
|
title: '封桥旧案',
|
|
visibility: 'visible',
|
|
summary: '封桥旧案再次被人提起。',
|
|
conflictType: '调查',
|
|
stakes: '边城安稳',
|
|
involvedFactionIds: [],
|
|
involvedActorIds: ['npc-1'],
|
|
relatedLocationIds: ['bridge'],
|
|
},
|
|
],
|
|
hiddenThreads: [],
|
|
scars: [
|
|
{
|
|
id: 'scar-1',
|
|
title: '断桥旧痕',
|
|
pastEvent: '封桥夜留下的旧痕。',
|
|
publicResidue: '桥柱上还留着旧封痕。',
|
|
hiddenTruth: '封桥令另有来头。',
|
|
relatedActorIds: ['npc-1'],
|
|
relatedLocationIds: ['bridge'],
|
|
},
|
|
],
|
|
motifs: [],
|
|
},
|
|
knowledgeFacts: null,
|
|
threadContracts: null,
|
|
};
|
|
|
|
describe('buildKnowledgeGraph', () => {
|
|
it('builds actor facts from narrative profile and backstory chapters', () => {
|
|
const facts = buildKnowledgeGraph(profile);
|
|
|
|
expect(facts.some((fact) => fact.title.includes('公开面'))).toBe(true);
|
|
expect(facts.some((fact) => fact.title.includes('禁区') && fact.visibility === 'forbidden')).toBe(true);
|
|
expect(facts.some((fact) => fact.title === '表层来意')).toBe(true);
|
|
});
|
|
});
|