import { describe, it, expect } from 'vitest'; import { loadYarnProject, loadYarnProjectSync, LoadError } from '../src/loader/index'; import { resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = fileURLToPath(new URL('.', import.meta.url)); describe('loadYarnProject', () => { it('should load a simple project', async () => { const projectPath = resolve(__dirname, 'fixtures/simple/.yarnproject'); const result = await loadYarnProject(projectPath); expect(result.project.projectFileVersion).toBe(4); expect(result.project.projectName).toBe('Simple Test Project'); expect(result.project.sourceFiles).toEqual(['**/*.yarn']); expect(result.project.baseLanguage).toBe('en'); expect(result.yarnFiles.length).toBeGreaterThan(0); }); it('should parse all yarn files in simple project', async () => { const projectPath = resolve(__dirname, 'fixtures/simple/.yarnproject'); const result = await loadYarnProject(projectPath); const titles = result.yarnFiles.flatMap(f => f.document.nodes.map(n => n.title)); expect(titles).toContain('Start'); expect(titles).toContain('Greeting'); expect(titles).toContain('AnotherNode'); }); it('should load a localised project', async () => { const projectPath = resolve(__dirname, 'fixtures/localised/.yarnproject'); const result = await loadYarnProject(projectPath); expect(result.project.projectName).toBe('Localised Project'); expect(result.project.baseLanguage).toBe('en'); expect(result.project.localisation).toBeDefined(); expect(result.project.localisation!['zh-Hans']).toBeDefined(); expect(result.yarnFiles.length).toBeGreaterThan(0); }); it('should load a complex project with multiple patterns', async () => { const projectPath = resolve(__dirname, 'fixtures/complex/.yarnproject'); const result = await loadYarnProject(projectPath); expect(result.project.projectFileVersion).toBe(4); expect(result.project.authorName).toEqual(['Author One', 'Author Two']); expect(result.project.sourceFiles).toContain('dialogue/**/*.yarn'); expect(result.project.sourceFiles).toContain('scripts/**/*.yarn'); }); it('should exclude files matching excludeFiles patterns', async () => { const projectPath = resolve(__dirname, 'fixtures/complex/.yarnproject'); const result = await loadYarnProject(projectPath); // Check that backup file is excluded const backupFiles = result.yarnFiles.filter(f => f.relativePath.includes('backup'), ); expect(backupFiles).toHaveLength(0); }); it('should include files from multiple source patterns', async () => { const projectPath = resolve(__dirname, 'fixtures/complex/.yarnproject'); const result = await loadYarnProject(projectPath); const relativePaths = result.yarnFiles.map(f => f.relativePath); // Should include dialogue files expect(relativePaths.some(p => p.includes('dialogue'))).toBe(true); // Should include script files expect(relativePaths.some(p => p.includes('scripts'))).toBe(true); }); it('should parse yarn documents correctly', async () => { const projectPath = resolve(__dirname, 'fixtures/simple/.yarnproject'); const result = await loadYarnProject(projectPath); const startNode = result.yarnFiles .flatMap(f => f.document.nodes) .find(n => n.title === 'Start'); expect(startNode).toBeDefined(); expect(startNode!.body.length).toBeGreaterThan(0); }); it('should handle nodes with tags', async () => { const projectPath = resolve(__dirname, 'fixtures/simple/.yarnproject'); const result = await loadYarnProject(projectPath); const greetingNode = result.yarnFiles .flatMap(f => f.document.nodes) .find(n => n.title === 'Greeting'); expect(greetingNode).toBeDefined(); expect(greetingNode!.nodeTags).toContain('greeting'); }); it('should throw LoadError for non-existent file', async () => { const projectPath = resolve(__dirname, 'fixtures/nonexistent/.yarnproject'); await expect(loadYarnProject(projectPath)).rejects.toThrow(LoadError); }); it('should throw error for invalid JSON', async () => { const projectPath = resolve(__dirname, 'fixtures/invalid/.yarnproject'); // This will fail because the fixture doesn't exist await expect(loadYarnProject(projectPath)).rejects.toThrow(); }); }); describe('loadYarnProjectSync', () => { it('should load a simple project synchronously', () => { const projectPath = resolve(__dirname, 'fixtures/simple/.yarnproject'); const result = loadYarnProjectSync(projectPath); expect(result.project.projectFileVersion).toBe(4); expect(result.yarnFiles.length).toBeGreaterThan(0); }); it('should parse all yarn files synchronously', () => { const projectPath = resolve(__dirname, 'fixtures/simple/.yarnproject'); const result = loadYarnProjectSync(projectPath); const titles = result.yarnFiles.flatMap(f => f.document.nodes.map(n => n.title)); expect(titles).toContain('Start'); }); });