#!/usr/bin/env node import assert from 'assert'; import express from 'express'; import fs from 'fs'; import os from 'os'; import path from 'path'; import { setupFileRoutes } from './src/server/routes/files.js'; import { setupWorkspaceRoutes } from './src/server/routes/workspace.js'; import { VL_CODE_HOME, loadInstances } from './src/server/helpers.js'; const WORKSPACES_FILE = path.join(VL_CODE_HOME, 'workspaces.json'); const INSTANCES_FILE = path.join(VL_CODE_HOME, 'instances.json'); async function main() { const createParent = fs.mkdtempSync(path.join(os.homedir(), 'vlcode-home-create-')); const openDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vlcode-open-workspace-')); const workspacesBackup = fs.existsSync(WORKSPACES_FILE) ? fs.readFileSync(WORKSPACES_FILE, 'utf8') : null; const instancesBackup = fs.existsSync(INSTANCES_FILE) ? fs.readFileSync(INSTANCES_FILE, 'utf8') : null; const app = express(); app.use(express.json({ limit: '10mb' })); const fakeServer = { config: { emptyWorkspaceDir: path.join(os.tmpdir(), 'vlcode-empty-window-route-test'), workDir: openDir, }, _serverPort: 4002, _openTabs: [], _workspaceStates: new Map(), _saveOpenTabs() {}, broadcast() {}, hasSelectedWorkspace() { return false; }, getVisibleWorkDir() { return ''; }, async switchWorkspace(dirPath) { return { ok: true, workDir: dirPath }; }, }; setupFileRoutes(app, fakeServer); setupWorkspaceRoutes(app, fakeServer); const httpServer = app.listen(0); await new Promise((resolve, reject) => { httpServer.once('listening', resolve); httpServer.once('error', reject); }); const { port } = httpServer.address(); let openedPort = null; try { const browseRes = await fetch(`http://127.0.0.1:${port}/api/browse-dir?path=${encodeURIComponent('~')}`); const browseBody = await browseRes.json(); assert.equal(browseRes.status, 200); assert.equal(browseBody.current, os.homedir(), 'tilde path should resolve to the real home directory'); const createParentTilde = `~/${path.basename(createParent)}`; const createRes = await fetch(`http://127.0.0.1:${port}/api/workspaces/create-project`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ projectName: 'TildeCreateRouteTest', parentDir: createParentTilde, }), }); const createBody = await createRes.json(); assert.equal(createRes.status, 200); assert.equal(createBody.path, path.join(createParent, 'TildeCreateRouteTest')); assert.ok(fs.existsSync(path.join(createBody.path, '.vl-code', 'project.json'))); const openRes = await fetch(`http://127.0.0.1:${port}/api/windows/open`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dirPath: openDir }), }); const openBody = await openRes.json(); assert.equal(openRes.status, 200, openBody.error || 'open route should succeed'); assert.equal(typeof openBody.port, 'number'); openedPort = openBody.port; const healthRes = await fetch(`http://127.0.0.1:${openedPort}/api/health`); const healthBody = await healthRes.json(); assert.equal(healthRes.status, 200); assert.equal(healthBody.ok, true); const closeRes = await fetch(`http://127.0.0.1:${port}/api/windows/${openedPort}`, { method: 'DELETE' }); const closeBody = await closeRes.json(); assert.equal(closeRes.status, 200); assert.equal(closeBody.ok, true); openedPort = null; } finally { if (openedPort) { const live = loadInstances().find((entry) => entry.port === openedPort); if (live) { try { process.kill(live.pid, 'SIGTERM'); } catch {} } } await new Promise((resolve) => httpServer.close(resolve)); fs.rmSync(createParent, { recursive: true, force: true }); fs.rmSync(openDir, { recursive: true, force: true }); if (workspacesBackup === null) fs.rmSync(WORKSPACES_FILE, { force: true }); else fs.writeFileSync(WORKSPACES_FILE, workspacesBackup, 'utf8'); if (instancesBackup === null) fs.rmSync(INSTANCES_FILE, { force: true }); else fs.writeFileSync(INSTANCES_FILE, instancesBackup, 'utf8'); } console.log('\n── Workspace Path Expansion ──'); console.log('PASS test-workspace-path-expansion.js'); } main().catch((err) => { console.error(err); process.exit(1); });