Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt standard monorepo conventions (apps/ for runnable apps, packages/ for reusable libraries). Update all config files, shared package imports, test fixtures, and documentation to reflect new paths. Key fixes: - Update workspace config to ["apps/*", "packages/*"] - Update tsconfig.json rootDir/include for apps/server/ - Add apps/web/** to vitest exclude list - Update drizzle.config.ts schema path - Fix ensure-schema.ts migration path detection (3 levels up in dev, 2 levels up in dist) - Fix tests/integration/cli-server.test.ts import paths - Update packages/shared imports to apps/server/ paths - Update all docs/ files with new paths
116 lines
2.8 KiB
TypeScript
116 lines
2.8 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { parseCwPreviewConfig } from './config-reader.js';
|
|
|
|
describe('parseCwPreviewConfig', () => {
|
|
it('parses minimal single-service config', () => {
|
|
const raw = `
|
|
version: 1
|
|
services:
|
|
app:
|
|
build: "."
|
|
port: 3000
|
|
`;
|
|
const config = parseCwPreviewConfig(raw);
|
|
expect(config.version).toBe(1);
|
|
expect(Object.keys(config.services)).toEqual(['app']);
|
|
expect(config.services.app.port).toBe(3000);
|
|
expect(config.services.app.build).toBe('.');
|
|
});
|
|
|
|
it('parses multi-service config with routes and healthchecks', () => {
|
|
const raw = `
|
|
version: 1
|
|
services:
|
|
frontend:
|
|
build:
|
|
context: "."
|
|
dockerfile: apps/web/Dockerfile
|
|
port: 3000
|
|
route: /
|
|
healthcheck:
|
|
path: /
|
|
interval: 5s
|
|
retries: 10
|
|
env:
|
|
VITE_API_URL: /api
|
|
backend:
|
|
build:
|
|
context: "."
|
|
dockerfile: packages/api/Dockerfile
|
|
port: 8080
|
|
route: /api
|
|
healthcheck:
|
|
path: /health
|
|
env:
|
|
DATABASE_URL: "postgres://db:5432/app"
|
|
db:
|
|
image: postgres:16-alpine
|
|
port: 5432
|
|
internal: true
|
|
env:
|
|
POSTGRES_PASSWORD: preview
|
|
`;
|
|
const config = parseCwPreviewConfig(raw);
|
|
|
|
expect(Object.keys(config.services)).toHaveLength(3);
|
|
|
|
// Frontend
|
|
expect(config.services.frontend.port).toBe(3000);
|
|
expect(config.services.frontend.route).toBe('/');
|
|
expect(config.services.frontend.healthcheck?.path).toBe('/');
|
|
expect(config.services.frontend.healthcheck?.retries).toBe(10);
|
|
expect(config.services.frontend.env?.VITE_API_URL).toBe('/api');
|
|
expect(config.services.frontend.build).toEqual({
|
|
context: '.',
|
|
dockerfile: 'apps/web/Dockerfile',
|
|
});
|
|
|
|
// Backend
|
|
expect(config.services.backend.port).toBe(8080);
|
|
expect(config.services.backend.route).toBe('/api');
|
|
|
|
// DB (internal)
|
|
expect(config.services.db.internal).toBe(true);
|
|
expect(config.services.db.image).toBe('postgres:16-alpine');
|
|
});
|
|
|
|
it('rejects config without services', () => {
|
|
expect(() => parseCwPreviewConfig('version: 1\n')).toThrow('missing "services"');
|
|
});
|
|
|
|
it('rejects service without port (unless internal)', () => {
|
|
const raw = `
|
|
version: 1
|
|
services:
|
|
app:
|
|
build: "."
|
|
`;
|
|
expect(() => parseCwPreviewConfig(raw)).toThrow('must specify a "port"');
|
|
});
|
|
|
|
it('allows internal service without port', () => {
|
|
const raw = `
|
|
version: 1
|
|
services:
|
|
redis:
|
|
image: redis:7
|
|
internal: true
|
|
`;
|
|
const config = parseCwPreviewConfig(raw);
|
|
expect(config.services.redis.internal).toBe(true);
|
|
expect(config.services.redis.port).toBe(0);
|
|
});
|
|
|
|
it('normalizes string build to string', () => {
|
|
const raw = `
|
|
version: 1
|
|
services:
|
|
app:
|
|
build: "./app"
|
|
port: 3000
|
|
`;
|
|
const config = parseCwPreviewConfig(raw);
|
|
expect(config.services.app.build).toBe('./app');
|
|
});
|
|
});
|