• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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