mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 12:09:03 +00:00
fix(tests): isolate tests from user ~/.ccs directory
Problem: Test suite was directly modifying user's personal ~/.ccs/ directory, causing configuration interference during development. Solution: - Add test-environment.js fixture with CCS_HOME env var support - Update postinstall.js to respect CCS_HOME for test isolation - Update config-manager.ts with getCcsHome() helper - Update postinstall.test.js and cli.test.js to use isolated env - Remove auto-install of .claude/ symlinks from postinstall (users can run "ccs sync" to opt-in) Benefits: - Tests run in temp directories, no user config affected - Users control when .claude/ items are installed via "ccs sync" - All 39 tests passing with proper isolation
This commit is contained in:
1 parent
1c3c4aade0
commit
49150dc24f
5 files changed
+278
-84
No files matched your search
+16
-27
@@ -12,14 +12,24 @@ const os = require('os');
|
||||
* Runs when: npm install -g @kaitranntt/ccs
|
||||
* Idempotent: Safe to run multiple times (won't overwrite existing configs)
|
||||
* Cross-platform: Works on Unix, macOS, Windows
|
||||
*
|
||||
* Test isolation: Set CCS_HOME env var to redirect all operations to a test directory
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the CCS home directory (respects CCS_HOME env var for test isolation)
|
||||
* @returns {string} Home directory path
|
||||
*/
|
||||
function getCcsHome() {
|
||||
return process.env.CCS_HOME || os.homedir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate created configuration files
|
||||
* @returns {object} { success: boolean, errors: string[], warnings: string[] }
|
||||
*/
|
||||
function validateConfiguration() {
|
||||
const homedir = os.homedir();
|
||||
const homedir = getCcsHome();
|
||||
const errors = [];
|
||||
const warnings = [];
|
||||
|
||||
@@ -63,8 +73,8 @@ function validateConfiguration() {
|
||||
|
||||
function createConfigFiles() {
|
||||
try {
|
||||
// Get user home directory (cross-platform)
|
||||
const homedir = os.homedir();
|
||||
// Get user home directory (cross-platform, respects CCS_HOME for test isolation)
|
||||
const homedir = getCcsHome();
|
||||
const ccsDir = path.join(homedir, '.ccs');
|
||||
|
||||
// Create ~/.ccs/ directory if missing
|
||||
@@ -106,30 +116,9 @@ function createConfigFiles() {
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Copy .claude/ directory from package to ~/.ccs/.claude/ (v4.1.1)
|
||||
try {
|
||||
const ClaudeDirInstaller = require('../dist/utils/claude-dir-installer').default;
|
||||
const installer = new ClaudeDirInstaller();
|
||||
const packageDir = path.join(__dirname, '..');
|
||||
installer.install(packageDir);
|
||||
|
||||
// Clean up deprecated files (v4.3.2)
|
||||
installer.cleanupDeprecated();
|
||||
} catch (err) {
|
||||
console.warn('[!] Failed to install .claude/ directory:', err.message);
|
||||
console.warn(' CCS items may not be available');
|
||||
}
|
||||
|
||||
// Install CCS items to ~/.claude/ (v4.1.0)
|
||||
try {
|
||||
const { ClaudeSymlinkManager } = require('../dist/utils/claude-symlink-manager');
|
||||
const claudeSymlinkManager = new ClaudeSymlinkManager();
|
||||
claudeSymlinkManager.install();
|
||||
} catch (err) {
|
||||
console.warn('[!] CCS item installation warning:', err.message);
|
||||
console.warn(' Run "ccs sync" to retry');
|
||||
}
|
||||
console.log('');
|
||||
// NOTE: .claude/ directory installation moved to "ccs sync" command
|
||||
// Users can run "ccs sync" to install CCS commands/skills to ~/.claude/
|
||||
// This gives users control over when to modify their Claude configuration
|
||||
|
||||
// Create config.json if missing
|
||||
const configPath = path.join(ccsDir, 'config.json');
|
||||
|
||||
@@ -9,11 +9,27 @@ import { error } from './helpers';
|
||||
// const { ErrorManager } = require('./error-manager');
|
||||
// const RecoveryManager = require('./recovery-manager');
|
||||
|
||||
/**
|
||||
* Get the CCS home directory (respects CCS_HOME env var for test isolation)
|
||||
* @returns Home directory path
|
||||
*/
|
||||
export function getCcsHome(): string {
|
||||
return process.env.CCS_HOME || os.homedir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CCS directory path (~/.ccs)
|
||||
* @returns Path to .ccs directory
|
||||
*/
|
||||
export function getCcsDir(): string {
|
||||
return path.join(getCcsHome(), '.ccs');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config file path
|
||||
*/
|
||||
export function getConfigPath(): string {
|
||||
return process.env.CCS_CONFIG || path.join(os.homedir(), '.ccs', 'config.json');
|
||||
return process.env.CCS_CONFIG || path.join(getCcsHome(), '.ccs', 'config.json');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Test Environment Isolation
|
||||
*
|
||||
* Provides isolated ~/.ccs/ directory for tests to prevent
|
||||
* interference with the user's actual CCS configuration.
|
||||
*
|
||||
* Usage:
|
||||
* const { createTestEnvironment } = require('../fixtures/test-environment');
|
||||
*
|
||||
* describe('my tests', () => {
|
||||
* let testEnv;
|
||||
*
|
||||
* before(() => {
|
||||
* testEnv = createTestEnvironment();
|
||||
* });
|
||||
*
|
||||
* after(() => {
|
||||
* testEnv.cleanup();
|
||||
* });
|
||||
*
|
||||
* it('test something', () => {
|
||||
* // Tests run with CCS_HOME pointing to temp directory
|
||||
* // Your test code here
|
||||
* });
|
||||
* });
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
/**
|
||||
* Create an isolated test environment
|
||||
* Sets CCS_HOME to a temporary directory and provides cleanup
|
||||
*
|
||||
* @returns {object} Test environment with paths and cleanup function
|
||||
*/
|
||||
function createTestEnvironment() {
|
||||
// Create unique temp directory for this test run
|
||||
const tempBase = path.join(os.tmpdir(), 'ccs-test');
|
||||
const uniqueId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
const testHome = path.join(tempBase, uniqueId);
|
||||
const testCcsDir = path.join(testHome, '.ccs');
|
||||
|
||||
// Create directories
|
||||
fs.mkdirSync(testCcsDir, { recursive: true });
|
||||
|
||||
// Store original environment
|
||||
const originalHome = process.env.HOME;
|
||||
const originalCcsHome = process.env.CCS_HOME;
|
||||
const originalUserProfile = process.env.USERPROFILE;
|
||||
|
||||
// Set test environment - use CCS_HOME for isolation
|
||||
process.env.CCS_HOME = testHome;
|
||||
|
||||
// Return environment object
|
||||
return {
|
||||
/** Path to the test home directory (like ~) */
|
||||
testHome,
|
||||
|
||||
/** Path to the test .ccs directory (like ~/.ccs) */
|
||||
ccsDir: testCcsDir,
|
||||
|
||||
/** Original HOME value for reference */
|
||||
originalHome,
|
||||
|
||||
/**
|
||||
* Get a path within the test CCS directory
|
||||
* @param {...string} parts - Path segments
|
||||
* @returns {string} Full path
|
||||
*/
|
||||
getCcsPath(...parts) {
|
||||
return path.join(testCcsDir, ...parts);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a file in the test CCS directory
|
||||
* @param {string} relativePath - Path relative to .ccs/
|
||||
* @param {string|object} content - File content (objects are JSON stringified)
|
||||
*/
|
||||
createFile(relativePath, content) {
|
||||
const fullPath = path.join(testCcsDir, relativePath);
|
||||
const dir = path.dirname(fullPath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
const data = typeof content === 'object' ? JSON.stringify(content, null, 2) : content;
|
||||
fs.writeFileSync(fullPath, data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Read a file from the test CCS directory
|
||||
* @param {string} relativePath - Path relative to .ccs/
|
||||
* @param {boolean} [asJson=false] - Parse as JSON
|
||||
* @returns {string|object} File content
|
||||
*/
|
||||
readFile(relativePath, asJson = false) {
|
||||
const fullPath = path.join(testCcsDir, relativePath);
|
||||
const content = fs.readFileSync(fullPath, 'utf8');
|
||||
return asJson ? JSON.parse(content) : content;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a file exists in the test CCS directory
|
||||
* @param {string} relativePath - Path relative to .ccs/
|
||||
* @returns {boolean}
|
||||
*/
|
||||
fileExists(relativePath) {
|
||||
return fs.existsSync(path.join(testCcsDir, relativePath));
|
||||
},
|
||||
|
||||
/**
|
||||
* Clean up the test environment and restore original settings
|
||||
*/
|
||||
cleanup() {
|
||||
// Restore original environment
|
||||
if (originalCcsHome !== undefined) {
|
||||
process.env.CCS_HOME = originalCcsHome;
|
||||
} else {
|
||||
delete process.env.CCS_HOME;
|
||||
}
|
||||
|
||||
// Clean up temp directory
|
||||
try {
|
||||
fs.rmSync(testHome, { recursive: true, force: true });
|
||||
} catch (err) {
|
||||
// Ignore cleanup errors
|
||||
console.warn(`[test-environment] Cleanup warning: ${err.message}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CCS home directory (respects CCS_HOME env var)
|
||||
* This should be used instead of os.homedir() for CCS paths
|
||||
*
|
||||
* @returns {string} Home directory path
|
||||
*/
|
||||
function getCcsHome() {
|
||||
return process.env.CCS_HOME || os.homedir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CCS directory path
|
||||
*
|
||||
* @returns {string} Path to .ccs directory
|
||||
*/
|
||||
function getCcsDir() {
|
||||
return path.join(getCcsHome(), '.ccs');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createTestEnvironment,
|
||||
getCcsHome,
|
||||
getCcsDir
|
||||
};
|
||||
+41
-22
@@ -1,28 +1,47 @@
|
||||
const assert = require('assert');
|
||||
const { execSync } = require('child_process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const { createTestEnvironment } = require('../fixtures/test-environment');
|
||||
|
||||
describe('npm CLI', () => {
|
||||
const ccsPath = path.join(__dirname, '..', '..', 'dist', 'ccs.js');
|
||||
const ccsDir = path.join(os.homedir(), '.ccs');
|
||||
const configPath = path.join(ccsDir, 'config.json');
|
||||
let testEnv;
|
||||
let testCcsHome;
|
||||
|
||||
before(() => {
|
||||
// Ensure CCS is installed and configured
|
||||
if (!fs.existsSync(configPath)) {
|
||||
const postinstallScript = path.join(__dirname, '..', '..', 'scripts', 'postinstall.js');
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
// Create isolated test environment
|
||||
testEnv = createTestEnvironment();
|
||||
testCcsHome = testEnv.testHome;
|
||||
|
||||
// Run postinstall to create config in test environment
|
||||
const postinstallScript = path.join(__dirname, '..', '..', 'scripts', 'postinstall.js');
|
||||
execSync(`node "${postinstallScript}"`, {
|
||||
stdio: 'ignore',
|
||||
env: { ...process.env, CCS_HOME: testCcsHome }
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
// Clean up test environment
|
||||
if (testEnv) {
|
||||
testEnv.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
// Helper to run CLI with test environment
|
||||
function runCli(args, options = {}) {
|
||||
return execSync(`node "${ccsPath}" ${args}`, {
|
||||
...options,
|
||||
env: { ...process.env, CCS_HOME: testCcsHome }
|
||||
});
|
||||
}
|
||||
|
||||
describe('Argument parsing', () => {
|
||||
it('handles flag -c without profile error', function() {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" -c`, { stdio: 'pipe' });
|
||||
runCli('-c', { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
// Should NOT show "Profile '-c' not found" error
|
||||
@@ -34,7 +53,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" --verbose`, { stdio: 'pipe' });
|
||||
runCli('--verbose', { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
assert(!output.includes("Profile '--verbose' not found"), 'Should not treat --verbose as profile');
|
||||
@@ -45,7 +64,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(10000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" -p "test prompt"`, { stdio: 'pipe', timeout: 8000 });
|
||||
runCli('-p "test prompt"', { stdio: 'pipe', timeout: 8000 });
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
assert(!output.includes("Profile '-p' not found"), 'Should not treat -p as profile');
|
||||
@@ -56,7 +75,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" -c --verbose`, { stdio: 'pipe' });
|
||||
runCli('-c --verbose', { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
assert(!output.includes("Profile '-c' not found"), 'Should not treat flags as profiles');
|
||||
@@ -70,7 +89,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" glm --help`, { stdio: 'pipe' });
|
||||
runCli('glm --help', { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || '';
|
||||
assert(!output.includes("Profile 'glm' not found"), 'GLM profile should exist');
|
||||
@@ -81,7 +100,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" invalid-profile-name`, { stdio: 'pipe' });
|
||||
runCli('invalid-profile-name', { stdio: 'pipe' });
|
||||
assert(false, 'Should have thrown an error for invalid profile');
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
@@ -93,7 +112,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}" glm -c`, { stdio: 'pipe' });
|
||||
runCli('glm -c', { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
const output = e.stderr?.toString() || '';
|
||||
assert(!output.includes("Profile 'glm' not found"), 'GLM profile should exist');
|
||||
@@ -106,28 +125,28 @@ describe('npm CLI', () => {
|
||||
it('shows version with --version flag', function() {
|
||||
this.timeout(5000);
|
||||
|
||||
const output = execSync(`node "${ccsPath}" --version`, { encoding: 'utf8' });
|
||||
const output = runCli('--version', { encoding: 'utf8' });
|
||||
assert(/\d+\.\d+\.\d+/.test(output), 'Should show version number');
|
||||
});
|
||||
|
||||
it('shows version with -v flag', function() {
|
||||
this.timeout(5000);
|
||||
|
||||
const output = execSync(`node "${ccsPath}" -v`, { encoding: 'utf8' });
|
||||
const output = runCli('-v', { encoding: 'utf8' });
|
||||
assert(/\d+\.\d+\.\d+/.test(output), 'Should show version number');
|
||||
});
|
||||
|
||||
it('shows help with --help flag', function() {
|
||||
this.timeout(5000);
|
||||
|
||||
const output = execSync(`node "${ccsPath}" --help`, { encoding: 'utf8' });
|
||||
const output = runCli('--help', { encoding: 'utf8' });
|
||||
assert(/usage|help|options/i.test(output), 'Should show help information');
|
||||
});
|
||||
|
||||
it('shows help with -h flag', function() {
|
||||
this.timeout(5000);
|
||||
|
||||
const output = execSync(`node "${ccsPath}" -h`, { encoding: 'utf8' });
|
||||
const output = runCli('-h', { encoding: 'utf8' });
|
||||
assert(/usage|help|options/i.test(output), 'Should show help information');
|
||||
});
|
||||
});
|
||||
@@ -137,7 +156,7 @@ describe('npm CLI', () => {
|
||||
this.timeout(5000);
|
||||
|
||||
try {
|
||||
execSync(`node "${ccsPath}"`, { stdio: 'pipe' });
|
||||
runCli('', { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
// Should either succeed or fail gracefully with a helpful error
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
@@ -150,7 +169,7 @@ describe('npm CLI', () => {
|
||||
|
||||
const longArg = 'a'.repeat(1000);
|
||||
try {
|
||||
execSync(`node "${ccsPath}" "${longArg}"`, { stdio: 'pipe' });
|
||||
runCli(`"${longArg}"`, { stdio: 'pipe' });
|
||||
} catch (e) {
|
||||
// Should handle gracefully, not crash
|
||||
const output = e.stderr?.toString() || e.stdout?.toString() || '';
|
||||
@@ -158,4 +177,4 @@ describe('npm CLI', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,53 +1,56 @@
|
||||
const assert = require('assert');
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const { createTestEnvironment } = require('../fixtures/test-environment');
|
||||
|
||||
describe('npm postinstall', () => {
|
||||
const ccsDir = path.join(os.homedir(), '.ccs');
|
||||
const configPath = path.join(ccsDir, 'config.json');
|
||||
const glmPath = path.join(ccsDir, 'glm.settings.json');
|
||||
let testEnv;
|
||||
const postinstallScript = path.join(__dirname, '..', '..', 'scripts', 'postinstall.js');
|
||||
|
||||
beforeEach(() => {
|
||||
// Clean slate before each test
|
||||
if (fs.existsSync(ccsDir)) {
|
||||
fs.rmSync(ccsDir, { recursive: true, force: true });
|
||||
}
|
||||
// Create isolated test environment for each test
|
||||
testEnv = createTestEnvironment();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
// Cleanup after all tests
|
||||
if (fs.existsSync(ccsDir)) {
|
||||
fs.rmSync(ccsDir, { recursive: true, force: true });
|
||||
afterEach(() => {
|
||||
// Clean up test environment
|
||||
if (testEnv) {
|
||||
testEnv.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it('creates config.json', () => {
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
execSync(`node "${postinstallScript}"`, {
|
||||
stdio: 'ignore',
|
||||
env: { ...process.env, CCS_HOME: testEnv.testHome }
|
||||
});
|
||||
|
||||
assert(fs.existsSync(configPath), 'config.json should be created');
|
||||
assert(testEnv.fileExists('config.json'), 'config.json should be created');
|
||||
|
||||
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
const config = testEnv.readFile('config.json', true);
|
||||
assert(config.profiles, 'config.json should have profiles');
|
||||
assert(typeof config.profiles === 'object', 'profiles should be an object');
|
||||
});
|
||||
|
||||
it('creates glm.settings.json', () => {
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
execSync(`node "${postinstallScript}"`, {
|
||||
stdio: 'ignore',
|
||||
env: { ...process.env, CCS_HOME: testEnv.testHome }
|
||||
});
|
||||
|
||||
assert(fs.existsSync(glmPath), 'glm.settings.json should be created');
|
||||
assert(testEnv.fileExists('glm.settings.json'), 'glm.settings.json should be created');
|
||||
|
||||
const glmSettings = JSON.parse(fs.readFileSync(glmPath, 'utf8'));
|
||||
const glmSettings = testEnv.readFile('glm.settings.json', true);
|
||||
assert(glmSettings.env, 'glm.settings.json should have env section');
|
||||
assert(glmSettings.env.ANTHROPIC_MODEL, 'should have ANTHROPIC_MODEL set');
|
||||
assert.strictEqual(glmSettings.env.ANTHROPIC_MODEL, 'glm-4.6');
|
||||
});
|
||||
|
||||
it('is idempotent', () => {
|
||||
const env = { ...process.env, CCS_HOME: testEnv.testHome };
|
||||
|
||||
// Run postinstall first time
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore', env });
|
||||
|
||||
// Create custom config
|
||||
const customConfig = {
|
||||
@@ -56,19 +59,22 @@ describe('npm postinstall', () => {
|
||||
glm: '~/.ccs/glm.settings.json'
|
||||
}
|
||||
};
|
||||
fs.writeFileSync(configPath, JSON.stringify(customConfig, null, 2));
|
||||
testEnv.createFile('config.json', customConfig);
|
||||
|
||||
// Run postinstall again
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore', env });
|
||||
|
||||
// Verify custom config preserved
|
||||
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
const config = testEnv.readFile('config.json', true);
|
||||
assert(config.profiles.custom, 'Custom profile should be preserved');
|
||||
assert.strictEqual(config.profiles.custom, '~/.custom.json');
|
||||
});
|
||||
|
||||
it('uses ASCII symbols', () => {
|
||||
const output = execSync(`node "${postinstallScript}"`, { encoding: 'utf8' });
|
||||
const output = execSync(`node "${postinstallScript}"`, {
|
||||
encoding: 'utf8',
|
||||
env: { ...process.env, CCS_HOME: testEnv.testHome }
|
||||
});
|
||||
|
||||
// Check for ASCII symbols [OK], [!], [X], [i] - not emojis
|
||||
assert(/\[(OK|!|X|i)\]/.test(output), 'Should use ASCII symbols, not emojis');
|
||||
@@ -80,23 +86,27 @@ describe('npm postinstall', () => {
|
||||
|
||||
it('handles existing directory gracefully', () => {
|
||||
// Create directory manually first
|
||||
fs.mkdirSync(ccsDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(ccsDir, 'existing.txt'), 'exists');
|
||||
testEnv.createFile('existing.txt', 'exists');
|
||||
|
||||
// Run postinstall
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
execSync(`node "${postinstallScript}"`, {
|
||||
stdio: 'ignore',
|
||||
env: { ...process.env, CCS_HOME: testEnv.testHome }
|
||||
});
|
||||
|
||||
// Verify existing file still exists and new files are created
|
||||
assert(fs.existsSync(path.join(ccsDir, 'existing.txt')), 'Existing files should be preserved');
|
||||
assert(fs.existsSync(configPath), 'config.json should be created');
|
||||
assert(fs.existsSync(glmPath), 'glm.settings.json should be created');
|
||||
assert(testEnv.fileExists('existing.txt'), 'Existing files should be preserved');
|
||||
assert(testEnv.fileExists('config.json'), 'config.json should be created');
|
||||
assert(testEnv.fileExists('glm.settings.json'), 'glm.settings.json should be created');
|
||||
});
|
||||
|
||||
it('does not create VERSION file', () => {
|
||||
execSync(`node "${postinstallScript}"`, { stdio: 'ignore' });
|
||||
execSync(`node "${postinstallScript}"`, {
|
||||
stdio: 'ignore',
|
||||
env: { ...process.env, CCS_HOME: testEnv.testHome }
|
||||
});
|
||||
|
||||
const versionPath = path.join(ccsDir, 'VERSION');
|
||||
// The postinstall script doesn't create VERSION file (only native install does)
|
||||
assert(!fs.existsSync(versionPath), 'VERSION file should NOT be created by npm postinstall');
|
||||
assert(!testEnv.fileExists('VERSION'), 'VERSION file should NOT be created by npm postinstall');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user