Files
glitternetwork--pinme/tests/background-install-status.test.mjs
2026-07-13 12:30:28 +08:00

145 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict';
import {
mkdirSync,
mkdtempSync,
existsSync,
rmSync,
utimesSync,
writeFileSync,
} from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { build } from 'esbuild';
import { test } from 'vitest';
async function loadHelper() {
const tempDir = mkdtempSync(path.join(tmpdir(), 'pinme-install-helper-'));
const outfile = path.join(tempDir, 'installProjectDependencies.cjs');
await build({
entryPoints: [path.resolve('bin/utils/installProjectDependencies.ts')],
outfile,
bundle: true,
platform: 'node',
format: 'cjs',
target: 'node18',
});
return import(pathToFileURL(outfile).href);
}
function makeProject() {
return mkdtempSync(path.join(tmpdir(), 'pinme-install-project-'));
}
test('readBackgroundInstallStatus treats fresh log-only markers as running', async () => {
const {
INSTALL_LOG_FILE,
readBackgroundInstallStatus,
} = await loadHelper();
const projectDir = makeProject();
try {
writeFileSync(path.join(projectDir, INSTALL_LOG_FILE), 'starting npm ci\n');
assert.deepEqual(readBackgroundInstallStatus(projectDir), {
status: 'running',
exitCode: null,
logPath: path.join(projectDir, INSTALL_LOG_FILE),
});
} finally {
rmSync(projectDir, { recursive: true, force: true });
}
});
test('readBackgroundInstallStatus detects stale log-only markers as interrupted', async () => {
const {
INSTALL_LOG_FILE,
readBackgroundInstallStatus,
} = await loadHelper();
const projectDir = makeProject();
const logPath = path.join(projectDir, INSTALL_LOG_FILE);
try {
mkdirSync(projectDir, { recursive: true });
writeFileSync(logPath, 'starting npm ci\n');
const staleTime = new Date(Date.now() - 2 * 60 * 1000);
utimesSync(logPath, staleTime, staleTime);
assert.deepEqual(readBackgroundInstallStatus(projectDir), {
status: 'interrupted',
exitCode: null,
logPath,
});
} finally {
rmSync(projectDir, { recursive: true, force: true });
}
});
test('readBackgroundInstallStatus detects dead background install pid as interrupted', async () => {
const {
INSTALL_LOG_FILE,
INSTALL_PID_FILE,
readBackgroundInstallStatus,
} = await loadHelper();
const projectDir = makeProject();
const logPath = path.join(projectDir, INSTALL_LOG_FILE);
try {
writeFileSync(logPath, 'starting npm ci\n');
writeFileSync(path.join(projectDir, INSTALL_PID_FILE), '999999999');
assert.deepEqual(readBackgroundInstallStatus(projectDir), {
status: 'interrupted',
exitCode: null,
logPath,
});
} finally {
rmSync(projectDir, { recursive: true, force: true });
}
});
test('stopBackgroundInstall clears a dead background install pid marker', async () => {
const {
INSTALL_LOG_FILE,
INSTALL_PID_FILE,
stopBackgroundInstall,
} = await loadHelper();
const projectDir = makeProject();
const logPath = path.join(projectDir, INSTALL_LOG_FILE);
const pidPath = path.join(projectDir, INSTALL_PID_FILE);
try {
writeFileSync(logPath, 'starting npm ci\n');
writeFileSync(pidPath, '999999999');
assert.equal(await stopBackgroundInstall(projectDir), false);
assert.equal(readFileExists(pidPath), false);
} finally {
rmSync(projectDir, { recursive: true, force: true });
}
});
test('buildBackgroundInstallCommand captures Windows npm exit code after command finishes', async () => {
const {
buildBackgroundInstallCommand,
} = await loadHelper();
const command = buildBackgroundInstallCommand(
'ci',
'C:\\Users\\Pin Me\\project\\.pinme-install.log',
'C:\\Users\\Pin Me\\project\\.pinme-install.exitcode',
'win32',
);
assert.deepEqual(command.shellArgs.slice(0, 4), ['/d', '/s', '/v:on', '/c']);
assert.match(command.shellArgs[4], /echo !errorlevel! >/);
assert.doesNotMatch(command.shellArgs[4], /%errorlevel%/);
assert.match(command.shellArgs[4], /"C:\\Users\\Pin Me\\project\\.pinme-install.log"/);
});
function readFileExists(filePath) {
return existsSync(filePath);
}