Makelore 2.0 initial clean snapshot
This commit is contained in:
110
tests/unit/project-package-template.test.ts
Normal file
110
tests/unit/project-package-template.test.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { cp, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { parse as parseYaml } from 'yaml';
|
||||
import {
|
||||
initializeWorksPackageTemplate,
|
||||
resolveWorksPackageTemplateDirectory,
|
||||
} from '@electron/opencode/project-package-template';
|
||||
|
||||
const temporaryDirectories: string[] = [];
|
||||
const resourcesDirectory = join(process.cwd(), 'resources');
|
||||
|
||||
async function temporaryDirectory(prefix: string): Promise<string> {
|
||||
const directory = await mkdtemp(join(tmpdir(), prefix));
|
||||
temporaryDirectories.push(directory);
|
||||
return directory;
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(temporaryDirectories.splice(0).map((directory) => rm(directory, { recursive: true, force: true })));
|
||||
});
|
||||
|
||||
describe('Works Square project package template', () => {
|
||||
it('copies the shared baseline and only the Web example for a standard project', async () => {
|
||||
const projectPath = await temporaryDirectory('niancode-works-template-web-');
|
||||
const result = await initializeWorksPackageTemplate(projectPath, 'standard-development', { resourcesDirectory });
|
||||
|
||||
expect(result.files).toEqual(expect.arrayContaining([
|
||||
'.dockerignore',
|
||||
'Dockerfile',
|
||||
'docker-compose.yml',
|
||||
'nginx.conf',
|
||||
'niancode.yml',
|
||||
'deploy/works-deploy-check.schema.json',
|
||||
'deploy/examples/works-deploy-check.web.json',
|
||||
'deploy/部署报告模板.md',
|
||||
]));
|
||||
expect((await stat(join(projectPath, 'deploy/examples/works-deploy-check.web.json'))).isFile()).toBe(true);
|
||||
await expect(stat(join(projectPath, 'deploy/examples/works-deploy-check.game.json'))).rejects.toMatchObject({ code: 'ENOENT' });
|
||||
for (const releaseArtifact of ['works-deploy-check.json', 'works-publish.json', '部署报告.md']) {
|
||||
await expect(stat(join(projectPath, releaseArtifact))).rejects.toMatchObject({ code: 'ENOENT' });
|
||||
}
|
||||
});
|
||||
|
||||
it('copies only the complete game/canvas example for a game project', async () => {
|
||||
const projectPath = await temporaryDirectory('niancode-works-template-game-');
|
||||
await initializeWorksPackageTemplate(projectPath, 'game-development', { resourcesDirectory });
|
||||
|
||||
const example = JSON.parse(await readFile(join(projectPath, 'deploy/examples/works-deploy-check.game.json'), 'utf8'));
|
||||
const evidence = example.checks.game_canvas_smoke.canvas_evidence;
|
||||
expect(example.status).toBe('BLOCKED');
|
||||
expect(evidence.resize_verified).toBe(false);
|
||||
for (const measurement of [
|
||||
evidence.logical_resolution,
|
||||
evidence.desktop_viewport,
|
||||
evidence.mobile_viewport,
|
||||
evidence.desktop_canvas,
|
||||
evidence.mobile_canvas,
|
||||
evidence.expected_max_canvas.desktop,
|
||||
evidence.expected_max_canvas.mobile,
|
||||
]) {
|
||||
expect(typeof measurement.width).toBe('number');
|
||||
expect(typeof measurement.height).toBe('number');
|
||||
expect(measurement.width).toBeGreaterThan(0);
|
||||
expect(measurement.height).toBeGreaterThan(0);
|
||||
}
|
||||
await expect(stat(join(projectPath, 'deploy/examples/works-deploy-check.web.json'))).rejects.toMatchObject({ code: 'ENOENT' });
|
||||
});
|
||||
|
||||
it('keeps the manifest, Compose, Nginx, schema, and examples parseable and contract-safe', async () => {
|
||||
const templateRoot = resolveWorksPackageTemplateDirectory(resourcesDirectory);
|
||||
const manifest = parseYaml(await readFile(join(templateRoot, 'niancode.yml'), 'utf8'));
|
||||
const compose = parseYaml(await readFile(join(templateRoot, 'docker-compose.yml'), 'utf8'));
|
||||
const nginx = await readFile(join(templateRoot, 'nginx.conf'), 'utf8');
|
||||
const schema = JSON.parse(await readFile(join(templateRoot, 'deploy/works-deploy-check.schema.json'), 'utf8'));
|
||||
const web = JSON.parse(await readFile(join(templateRoot, 'deploy/examples/works-deploy-check.web.json'), 'utf8'));
|
||||
const game = JSON.parse(await readFile(join(templateRoot, 'deploy/examples/works-deploy-check.game.json'), 'utf8'));
|
||||
|
||||
expect(manifest).toEqual({ runtime: 'compose', compose: { file: 'docker-compose.yml', public_service: 'frontend', public_port: 8080 } });
|
||||
expect(compose.services.frontend.ports).toContain('127.0.0.1::8080');
|
||||
expect(nginx).toContain('listen 0.0.0.0:8080');
|
||||
expect(schema.properties.schema_version.const).toBe(1);
|
||||
expect(web.checks).not.toHaveProperty('game_canvas_smoke');
|
||||
expect(game.checks).toHaveProperty('game_canvas_smoke');
|
||||
});
|
||||
|
||||
it('rejects invalid JSON with a source-relative error and never overwrites a destination file', async () => {
|
||||
const fixtureResources = await temporaryDirectory('niancode-works-template-fixture-');
|
||||
await cp(resolveWorksPackageTemplateDirectory(resourcesDirectory), resolveWorksPackageTemplateDirectory(fixtureResources), { recursive: true });
|
||||
await writeFile(join(resolveWorksPackageTemplateDirectory(fixtureResources), 'deploy/examples/works-deploy-check.web.json'), '{invalid', 'utf8');
|
||||
const invalidProject = await temporaryDirectory('niancode-works-template-invalid-');
|
||||
await expect(initializeWorksPackageTemplate(invalidProject, 'standard-development', { resourcesDirectory: fixtureResources }))
|
||||
.rejects.toThrow('deploy/examples/works-deploy-check.web.json');
|
||||
|
||||
const existingProject = await temporaryDirectory('niancode-works-template-existing-');
|
||||
await writeFile(join(existingProject, 'niancode.yml'), 'user-owned', 'utf8');
|
||||
await expect(initializeWorksPackageTemplate(existingProject, 'standard-development', { resourcesDirectory }))
|
||||
.rejects.toThrow('niancode.yml');
|
||||
expect(await readFile(join(existingProject, 'niancode.yml'), 'utf8')).toBe('user-owned');
|
||||
});
|
||||
|
||||
it('is included by the packaged resources rule', async () => {
|
||||
const builderConfig = parseYaml(await readFile(join(process.cwd(), 'electron-builder.yml'), 'utf8'));
|
||||
expect(builderConfig.extraResources).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ from: 'resources/', to: 'resources/' }),
|
||||
]));
|
||||
expect((await stat(resolveWorksPackageTemplateDirectory(resourcesDirectory))).isDirectory()).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user