Files
Genarrative/src/data/sceneBackgrounds.test.ts
高物 bd9fdcbe31
Some checks failed
CI / verify (push) Has been cancelled
Implement scene-based chapter quest progression
2026-04-08 11:58:47 +08:00

122 lines
4.2 KiB
TypeScript

import fs from 'node:fs';
import path from 'node:path';
import { CustomWorldProfile, WorldType } from '../types';
import {
getDefaultCustomWorldSceneImage,
resolveCustomWorldCampSceneImage,
resolveCustomWorldLandmarkImageMap,
} from './customWorldVisuals';
import { getScenePresetsByWorld } from './scenePresets';
function resolvePublicAssetPath(assetPath: string) {
return path.resolve(process.cwd(), 'public', assetPath.replace(/^\/+/, ''));
}
describe('scene background assets', () => {
it('ships background files for every wuxia and xianxia scene preset', () => {
const scenes = [
...getScenePresetsByWorld(WorldType.WUXIA),
...getScenePresetsByWorld(WorldType.XIANXIA),
];
expect(scenes.length).toBeGreaterThan(0);
for (const scene of scenes) {
expect(fs.existsSync(resolvePublicAssetPath(scene.imageSrc))).toBe(true);
}
});
it('returns existing default custom world backgrounds for both anchor worlds', () => {
const wuxiaImage = getDefaultCustomWorldSceneImage('seed', 0, WorldType.WUXIA);
const xianxiaImage = getDefaultCustomWorldSceneImage('seed', 0, WorldType.XIANXIA);
expect(fs.existsSync(resolvePublicAssetPath(wuxiaImage))).toBe(true);
expect(fs.existsSync(resolvePublicAssetPath(xianxiaImage))).toBe(true);
});
it('keeps ungenerated custom world scenes on independent matched backgrounds', () => {
const generatedImage =
'/generated-custom-world-scenes/test-world/generated-ruins.png';
const profile: CustomWorldProfile = {
id: 'custom-world-test',
settingText: '荒城断碑与边关旧营并存的武侠世界',
name: '断碑边城',
subtitle: '烽烟未熄',
summary: '边关旧营与残城废墟彼此相望,玩家要追查旧案余烬。',
tone: '压抑、克制、潜伏危机',
playerGoal: '追查残城旧案背后的真相',
templateWorldType: WorldType.WUXIA,
majorFactions: [],
coreConflicts: ['边关旧案复起'],
attributeSchema: {
id: 'schema:test',
worldId: 'custom:test',
schemaVersion: 1,
generatedFrom: {
worldType: WorldType.CUSTOM,
worldName: '断碑边城',
settingSummary: '边关旧案',
tone: '压抑',
conflictCore: '旧案复起',
},
slots: [],
},
playableNpcs: [],
storyNpcs: [],
items: [],
landmarks: [
{
id: 'landmark-1',
name: '残城旧营',
description: '断墙、军帐与营火灰烬混在一起,像一处被遗弃的边关驻地。',
dangerLevel: 'high',
imageSrc: generatedImage,
sceneNpcIds: [],
connections: [],
},
{
id: 'landmark-2',
name: '雾锁渡桥',
description: '古桥横跨冷河,雾气压在水面上,只有残灯还在摇晃。',
dangerLevel: 'medium',
sceneNpcIds: [],
connections: [],
},
{
id: 'landmark-3',
name: '地宫裂隙',
description: '墓道向下坍塌,石阶与机关残痕一路通往地底深处。',
dangerLevel: 'extreme',
sceneNpcIds: [],
connections: [],
},
],
themePack: null,
storyGraph: null,
creatorIntent: null,
anchorPack: null,
lockState: null,
generationMode: 'full',
generationStatus: 'complete',
};
const landmarkImageMap = resolveCustomWorldLandmarkImageMap(profile);
const secondImage = landmarkImageMap.get('landmark-2');
const thirdImage = landmarkImageMap.get('landmark-3');
const campImage = resolveCustomWorldCampSceneImage(profile);
expect(landmarkImageMap.get('landmark-1')).toBe(generatedImage);
expect(secondImage).toBeTruthy();
expect(thirdImage).toBeTruthy();
expect(secondImage).not.toBe(generatedImage);
expect(thirdImage).not.toBe(generatedImage);
expect(secondImage).not.toBe(thirdImage);
expect(campImage).toBeTruthy();
expect(campImage).not.toBe(generatedImage);
expect(fs.existsSync(resolvePublicAssetPath(secondImage!))).toBe(true);
expect(fs.existsSync(resolvePublicAssetPath(thirdImage!))).toBe(true);
expect(fs.existsSync(resolvePublicAssetPath(campImage))).toBe(true);
});
});