实现小游戏与小程序项目创建发布
This commit is contained in:
@@ -3,6 +3,7 @@ import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { initializeProjectDirectory } from '@electron/opencode/project-directory-initialization';
|
||||
import type { ProjectType } from '../../shared/project-config';
|
||||
|
||||
const temporaryDirectories: string[] = [];
|
||||
|
||||
@@ -13,6 +14,98 @@ afterEach(async () => {
|
||||
});
|
||||
|
||||
describe('project directory initialization', () => {
|
||||
it.each([
|
||||
['mini_game', ['game.json', 'game.js']],
|
||||
['mini_program', ['app.json', 'app.js', join('pages', 'index', 'index.js')]],
|
||||
] satisfies Array<[ProjectType, string[]]>)('creates a complete %s Vite project template', async (projectType, typeFiles) => {
|
||||
const parentPath = await mkdtemp(join(tmpdir(), 'makelore-project-parent-'));
|
||||
temporaryDirectories.push(parentPath);
|
||||
const projectPath = join(parentPath, projectType);
|
||||
|
||||
const result = await initializeProjectDirectory({
|
||||
projectPath,
|
||||
projectType,
|
||||
allowExistingDirectory: false,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
reusedExistingConfig: false,
|
||||
config: { projectType },
|
||||
});
|
||||
const packageJson = JSON.parse(await readFile(join(projectPath, 'package.json'), 'utf8')) as {
|
||||
scripts: Record<string, string>;
|
||||
devDependencies: Record<string, string>;
|
||||
};
|
||||
const packageLock = JSON.parse(await readFile(join(projectPath, 'package-lock.json'), 'utf8')) as {
|
||||
lockfileVersion: number;
|
||||
packages: Record<string, unknown>;
|
||||
};
|
||||
expect(packageJson.scripts.build).toBe('vite build');
|
||||
expect(packageJson.devDependencies.vite).toBe('7.3.1');
|
||||
expect(packageLock.lockfileVersion).toBe(3);
|
||||
expect(packageLock.packages['node_modules/vite']).toBeTruthy();
|
||||
await expect(readFile(join(projectPath, 'index.html'), 'utf8')).resolves.toContain('type="module"');
|
||||
for (const relativePath of typeFiles) {
|
||||
await expect(readFile(join(projectPath, relativePath), 'utf8')).resolves.not.toBe('');
|
||||
}
|
||||
});
|
||||
|
||||
it('keeps custom projects on the existing minimal project structure', async () => {
|
||||
const parentPath = await mkdtemp(join(tmpdir(), 'makelore-custom-parent-'));
|
||||
temporaryDirectories.push(parentPath);
|
||||
const projectPath = join(parentPath, 'custom-project');
|
||||
|
||||
const result = await initializeProjectDirectory({
|
||||
projectPath,
|
||||
projectType: 'custom',
|
||||
allowExistingDirectory: false,
|
||||
});
|
||||
|
||||
expect(result.config.projectType).toBe('custom');
|
||||
expect((await readdir(projectPath)).sort()).toEqual(['.niancode', 'TASKS.md', 'VERSION.md', 'knowledge']);
|
||||
});
|
||||
|
||||
it('reuses an existing project only when an explicitly selected type matches', async () => {
|
||||
const parentPath = await mkdtemp(join(tmpdir(), 'makelore-existing-parent-'));
|
||||
temporaryDirectories.push(parentPath);
|
||||
const projectPath = join(parentPath, 'existing-project');
|
||||
await initializeProjectDirectory({
|
||||
projectPath,
|
||||
projectType: 'mini_game',
|
||||
allowExistingDirectory: false,
|
||||
});
|
||||
|
||||
await expect(initializeProjectDirectory({
|
||||
projectPath,
|
||||
projectType: 'mini_game',
|
||||
allowExistingDirectory: true,
|
||||
})).resolves.toMatchObject({ reusedExistingConfig: true, config: { projectType: 'mini_game' } });
|
||||
await expect(initializeProjectDirectory({
|
||||
projectPath,
|
||||
projectType: 'mini_program',
|
||||
allowExistingDirectory: true,
|
||||
})).rejects.toThrow('已有项目类型不可更改');
|
||||
await expect(initializeProjectDirectory({
|
||||
projectPath,
|
||||
allowExistingDirectory: true,
|
||||
})).resolves.toMatchObject({ reusedExistingConfig: true, config: { projectType: 'mini_game' } });
|
||||
});
|
||||
|
||||
it('does not change an existing folder when a publishable template file conflicts', async () => {
|
||||
const projectPath = await mkdtemp(join(tmpdir(), 'makelore-template-conflict-'));
|
||||
temporaryDirectories.push(projectPath);
|
||||
await writeFile(join(projectPath, 'package.json'), '{"name":"user-project"}\n', 'utf8');
|
||||
|
||||
await expect(initializeProjectDirectory({
|
||||
projectPath,
|
||||
projectType: 'mini_game',
|
||||
allowExistingDirectory: true,
|
||||
})).rejects.toThrow('Project initialization conflict: package.json already exists');
|
||||
|
||||
expect((await readdir(projectPath)).sort()).toEqual(['package.json']);
|
||||
await expect(readFile(join(projectPath, 'package.json'), 'utf8')).resolves.toBe('{"name":"user-project"}\n');
|
||||
});
|
||||
|
||||
it('rolls back only files and directories created by a failed in-place merge', async () => {
|
||||
const projectPath = await mkdtemp(join(tmpdir(), 'niancode-in-place-rollback-'));
|
||||
temporaryDirectories.push(projectPath);
|
||||
|
||||
Reference in New Issue
Block a user