1'use strict'; 2const common = require('../common'); 3const fixtures = require('../common/fixtures'); 4const assert = require('assert'); 5const path = require('path'); 6const fs = require('fs'); 7const { COPYFILE_FICLONE } = fs.constants; 8const child_process = require('child_process'); 9const pkgName = 'foo'; 10const { addLibraryPath } = require('../common/shared-lib-util'); 11 12addLibraryPath(process.env); 13 14if (process.argv[2] === 'child') { 15 console.log(require(pkgName).string); 16} else { 17 const tmpdir = require('../common/tmpdir'); 18 tmpdir.refresh(); 19 20 // Copy node binary into a test $PREFIX directory. 21 const prefixPath = path.join(tmpdir.path, 'install'); 22 fs.mkdirSync(prefixPath); 23 let testExecPath; 24 if (common.isWindows) { 25 testExecPath = path.join(prefixPath, path.basename(process.execPath)); 26 } else { 27 const prefixBinPath = path.join(prefixPath, 'bin'); 28 fs.mkdirSync(prefixBinPath); 29 testExecPath = path.join(prefixBinPath, path.basename(process.execPath)); 30 } 31 const mode = fs.statSync(process.execPath).mode; 32 fs.copyFileSync(process.execPath, testExecPath, COPYFILE_FICLONE); 33 fs.chmodSync(testExecPath, mode); 34 35 const runTest = (expectedString, env) => { 36 const child = child_process.execFileSync(testExecPath, 37 [ __filename, 'child' ], 38 { encoding: 'utf8', env: env }); 39 assert.strictEqual(child.trim(), expectedString); 40 }; 41 42 const testFixturesDir = fixtures.path(path.basename(__filename, '.js')); 43 44 const env = { ...process.env }; 45 // Unset NODE_PATH. 46 delete env.NODE_PATH; 47 48 // Test empty global path. 49 const noPkgHomeDir = path.join(tmpdir.path, 'home-no-pkg'); 50 fs.mkdirSync(noPkgHomeDir); 51 env.HOME = env.USERPROFILE = noPkgHomeDir; 52 assert.throws( 53 () => { 54 child_process.execFileSync(testExecPath, [ __filename, 'child' ], 55 { encoding: 'utf8', env: env }); 56 }, 57 new RegExp(`Cannot find module '${pkgName}'`)); 58 59 // Test module in $HOME/.node_modules. 60 const modHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_modules'); 61 env.HOME = env.USERPROFILE = modHomeDir; 62 runTest('$HOME/.node_modules', env); 63 64 // Test module in $HOME/.node_libraries. 65 const libHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_libraries'); 66 env.HOME = env.USERPROFILE = libHomeDir; 67 runTest('$HOME/.node_libraries', env); 68 69 // Test module both $HOME/.node_modules and $HOME/.node_libraries. 70 const bothHomeDir = path.join(testFixturesDir, 'home-pkg-in-both'); 71 env.HOME = env.USERPROFILE = bothHomeDir; 72 runTest('$HOME/.node_modules', env); 73 74 // Test module in $PREFIX/lib/node. 75 // Write module into $PREFIX/lib/node. 76 const expectedString = '$PREFIX/lib/node'; 77 const prefixLibPath = path.join(prefixPath, 'lib'); 78 fs.mkdirSync(prefixLibPath); 79 const prefixLibNodePath = path.join(prefixLibPath, 'node'); 80 fs.mkdirSync(prefixLibNodePath); 81 const pkgPath = path.join(prefixLibNodePath, `${pkgName}.js`); 82 fs.writeFileSync(pkgPath, `exports.string = '${expectedString}';`); 83 84 env.HOME = env.USERPROFILE = noPkgHomeDir; 85 runTest(expectedString, env); 86 87 // Test module in all global folders. 88 env.HOME = env.USERPROFILE = bothHomeDir; 89 runTest('$HOME/.node_modules', env); 90 91 // Test module in NODE_PATH is loaded ahead of global folders. 92 env.HOME = env.USERPROFILE = bothHomeDir; 93 env.NODE_PATH = path.join(testFixturesDir, 'node_path'); 94 runTest('$NODE_PATH', env); 95 96 // Test module in local folder is loaded ahead of global folders. 97 const localDir = path.join(testFixturesDir, 'local-pkg'); 98 env.HOME = env.USERPROFILE = bothHomeDir; 99 env.NODE_PATH = path.join(testFixturesDir, 'node_path'); 100 const child = child_process.execFileSync(testExecPath, 101 [ path.join(localDir, 'test.js') ], 102 { encoding: 'utf8', env: env }); 103 assert.strictEqual(child.trim(), 'local'); 104} 105