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'); }); });