feat: upgrade yarn-spinner-loader to 0.2.0 and add encounters.yarnproject test

This commit is contained in:
hypercross 2026-04-15 10:19:03 +08:00
parent 8f34104332
commit 5860f2a247
7 changed files with 123 additions and 5 deletions

8
package-lock.json generated
View File

@ -15,7 +15,7 @@
"tsup": "^8.0.2", "tsup": "^8.0.2",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vitest": "^1.3.1", "vitest": "^1.3.1",
"yarn-spinner-loader": "^0.1.1" "yarn-spinner-loader": "^0.2.0"
}, },
"peerDependencies": { "peerDependencies": {
"@preact/signals-core": "^1.5.1", "@preact/signals-core": "^1.5.1",
@ -3096,9 +3096,9 @@
} }
}, },
"node_modules/yarn-spinner-loader": { "node_modules/yarn-spinner-loader": {
"version": "0.1.1", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/yarn-spinner-loader/-/yarn-spinner-loader-0.1.1.tgz", "resolved": "https://registry.npmjs.org/yarn-spinner-loader/-/yarn-spinner-loader-0.2.0.tgz",
"integrity": "sha512-q1xC8QQghpZ1mJDgbnNVzVv3xtb6nOO7fC2YmFANHjz31tNfuf7jOZ1n+V80/5CUxK6ct5425XWYJpSRW/fWrw==", "integrity": "sha512-tWq+n7qziugn7pj+0Zf/XXWXqVxXZez1JkqQgk7JJD4yikHbY1OihYwqSvsUiNeav52j5VCrpU8vWlerwCawPw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@ -35,7 +35,7 @@
"tsup": "^8.0.2", "tsup": "^8.0.2",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vitest": "^1.3.1", "vitest": "^1.3.1",
"yarn-spinner-loader": "^0.1.1" "yarn-spinner-loader": "^0.2.0"
}, },
"keywords": [ "keywords": [
"boardgame", "boardgame",

5
src/global.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare module '*.yarnproject' {
import type { LoadResult } from 'yarn-spinner-loader';
const result: LoadResult;
export default result;
}

View File

@ -0,0 +1,17 @@
{
"projectFileVersion": 4,
"sourceFiles": [
"**/*.yarn"
],
"excludeFiles": [],
"baseLanguage": "en",
"projectName": "encounters",
"authorName": [
"hyper"
],
"editorOptions": {
"yarnScriptEditor": {
"presenter": "try"
}
}
}

View File

@ -0,0 +1,42 @@
title: Start
---
// A linear story progresses from one scene to the next.
// Great for cutscenes, tutorials, or scripted sequences.
<<jump Scene1>>
===
title: Scene1
---
The sun rose over the quiet village.
Birds sang their morning chorus as the first rays of light crept through the window.
-> Continue
<<jump Scene2>>
===
title: Scene2
---
In the kitchen, a kettle began to whistle.
The smell of fresh bread filled the air.
-> Continue
<<jump Scene3>>
===
title: Scene3
---
A knock at the door broke the peaceful morning.
Who could be visiting so early?
-> Open the door
<<jump Scene4>>
===
title: Scene4
---
A messenger stood at the threshold, parchment in hand.
"News from the capital," they said breathlessly. "You must read this at once."
// Your story continues from here!
===

View File

@ -0,0 +1 @@
export {default as encounters} from './encounters/encounters.yarnproject';

View File

@ -0,0 +1,53 @@
import { describe, it, expect } from 'vitest';
import encounters from '@/samples/slay-the-spire-like/dialogue/encounters/encounters.yarnproject';
describe('encounters.yarnproject import', () => {
it('should load the yarnproject with expected project metadata', () => {
expect(encounters.project.projectName).toBe('encounters');
expect(encounters.project.baseLanguage).toBe('en');
expect(encounters.project.authorName).toContain('hyper');
expect(encounters.project.projectFileVersion).toBe(4);
});
it('should have sourceFiles configured', () => {
expect(encounters.project.sourceFiles).toContain('**/*.yarn');
});
it('should have a valid baseDir', () => {
expect(typeof encounters.baseDir).toBe('string');
expect(encounters.baseDir.length).toBeGreaterThan(0);
});
it('should compile nodes from .yarn files', () => {
const nodeTitles = Object.keys(encounters.program.nodes);
expect(nodeTitles.length).toBeGreaterThan(0);
});
it('should contain expected nodes from story.yarn', () => {
const nodeTitles = Object.keys(encounters.program.nodes);
expect(nodeTitles).toContain('Start');
expect(nodeTitles).toContain('Scene1');
expect(nodeTitles).toContain('Scene2');
expect(nodeTitles).toContain('Scene3');
expect(nodeTitles).toContain('Scene4');
});
it('should have instructions in each node', () => {
for (const [title, node] of Object.entries(encounters.program.nodes)) {
if ('instructions' in node && Array.isArray((node as any).instructions)) {
expect((node as any).instructions.length).toBeGreaterThan(0);
}
}
});
it('should have Start node with jump instruction to Scene1', () => {
const startNode = encounters.program.nodes['Start'];
if ('instructions' in startNode) {
const jumpInstruction = startNode.instructions.find(
(instr) => instr.op === 'jump',
);
expect(jumpInstruction).toBeDefined();
expect(jumpInstruction!.target).toBe('Scene1');
}
});
});