11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst path = require('path');
61cb0ef41Sopenharmony_ciconst fs = require('fs');
71cb0ef41Sopenharmony_ciconst { COPYFILE_FICLONE } = fs.constants;
81cb0ef41Sopenharmony_ciconst child_process = require('child_process');
91cb0ef41Sopenharmony_ciconst pkgName = 'foo';
101cb0ef41Sopenharmony_ciconst { addLibraryPath } = require('../common/shared-lib-util');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciaddLibraryPath(process.env);
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciif (process.argv[2] === 'child') {
151cb0ef41Sopenharmony_ci  console.log(require(pkgName).string);
161cb0ef41Sopenharmony_ci} else {
171cb0ef41Sopenharmony_ci  const tmpdir = require('../common/tmpdir');
181cb0ef41Sopenharmony_ci  tmpdir.refresh();
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  // Copy node binary into a test $PREFIX directory.
211cb0ef41Sopenharmony_ci  const prefixPath = path.join(tmpdir.path, 'install');
221cb0ef41Sopenharmony_ci  fs.mkdirSync(prefixPath);
231cb0ef41Sopenharmony_ci  let testExecPath;
241cb0ef41Sopenharmony_ci  if (common.isWindows) {
251cb0ef41Sopenharmony_ci    testExecPath = path.join(prefixPath, path.basename(process.execPath));
261cb0ef41Sopenharmony_ci  } else {
271cb0ef41Sopenharmony_ci    const prefixBinPath = path.join(prefixPath, 'bin');
281cb0ef41Sopenharmony_ci    fs.mkdirSync(prefixBinPath);
291cb0ef41Sopenharmony_ci    testExecPath = path.join(prefixBinPath, path.basename(process.execPath));
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci  const mode = fs.statSync(process.execPath).mode;
321cb0ef41Sopenharmony_ci  fs.copyFileSync(process.execPath, testExecPath, COPYFILE_FICLONE);
331cb0ef41Sopenharmony_ci  fs.chmodSync(testExecPath, mode);
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  const runTest = (expectedString, env) => {
361cb0ef41Sopenharmony_ci    const child = child_process.execFileSync(testExecPath,
371cb0ef41Sopenharmony_ci                                             [ __filename, 'child' ],
381cb0ef41Sopenharmony_ci                                             { encoding: 'utf8', env: env });
391cb0ef41Sopenharmony_ci    assert.strictEqual(child.trim(), expectedString);
401cb0ef41Sopenharmony_ci  };
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  const testFixturesDir = fixtures.path(path.basename(__filename, '.js'));
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  const env = { ...process.env };
451cb0ef41Sopenharmony_ci  // Unset NODE_PATH.
461cb0ef41Sopenharmony_ci  delete env.NODE_PATH;
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  // Test empty global path.
491cb0ef41Sopenharmony_ci  const noPkgHomeDir = path.join(tmpdir.path, 'home-no-pkg');
501cb0ef41Sopenharmony_ci  fs.mkdirSync(noPkgHomeDir);
511cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = noPkgHomeDir;
521cb0ef41Sopenharmony_ci  assert.throws(
531cb0ef41Sopenharmony_ci    () => {
541cb0ef41Sopenharmony_ci      child_process.execFileSync(testExecPath, [ __filename, 'child' ],
551cb0ef41Sopenharmony_ci                                 { encoding: 'utf8', env: env });
561cb0ef41Sopenharmony_ci    },
571cb0ef41Sopenharmony_ci    new RegExp(`Cannot find module '${pkgName}'`));
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  // Test module in $HOME/.node_modules.
601cb0ef41Sopenharmony_ci  const modHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_modules');
611cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = modHomeDir;
621cb0ef41Sopenharmony_ci  runTest('$HOME/.node_modules', env);
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  // Test module in $HOME/.node_libraries.
651cb0ef41Sopenharmony_ci  const libHomeDir = path.join(testFixturesDir, 'home-pkg-in-node_libraries');
661cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = libHomeDir;
671cb0ef41Sopenharmony_ci  runTest('$HOME/.node_libraries', env);
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  // Test module both $HOME/.node_modules and $HOME/.node_libraries.
701cb0ef41Sopenharmony_ci  const bothHomeDir = path.join(testFixturesDir, 'home-pkg-in-both');
711cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = bothHomeDir;
721cb0ef41Sopenharmony_ci  runTest('$HOME/.node_modules', env);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  // Test module in $PREFIX/lib/node.
751cb0ef41Sopenharmony_ci  // Write module into $PREFIX/lib/node.
761cb0ef41Sopenharmony_ci  const expectedString = '$PREFIX/lib/node';
771cb0ef41Sopenharmony_ci  const prefixLibPath = path.join(prefixPath, 'lib');
781cb0ef41Sopenharmony_ci  fs.mkdirSync(prefixLibPath);
791cb0ef41Sopenharmony_ci  const prefixLibNodePath = path.join(prefixLibPath, 'node');
801cb0ef41Sopenharmony_ci  fs.mkdirSync(prefixLibNodePath);
811cb0ef41Sopenharmony_ci  const pkgPath = path.join(prefixLibNodePath, `${pkgName}.js`);
821cb0ef41Sopenharmony_ci  fs.writeFileSync(pkgPath, `exports.string = '${expectedString}';`);
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = noPkgHomeDir;
851cb0ef41Sopenharmony_ci  runTest(expectedString, env);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  // Test module in all global folders.
881cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = bothHomeDir;
891cb0ef41Sopenharmony_ci  runTest('$HOME/.node_modules', env);
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  // Test module in NODE_PATH is loaded ahead of global folders.
921cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = bothHomeDir;
931cb0ef41Sopenharmony_ci  env.NODE_PATH = path.join(testFixturesDir, 'node_path');
941cb0ef41Sopenharmony_ci  runTest('$NODE_PATH', env);
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  // Test module in local folder is loaded ahead of global folders.
971cb0ef41Sopenharmony_ci  const localDir = path.join(testFixturesDir, 'local-pkg');
981cb0ef41Sopenharmony_ci  env.HOME = env.USERPROFILE = bothHomeDir;
991cb0ef41Sopenharmony_ci  env.NODE_PATH = path.join(testFixturesDir, 'node_path');
1001cb0ef41Sopenharmony_ci  const child = child_process.execFileSync(testExecPath,
1011cb0ef41Sopenharmony_ci                                           [ path.join(localDir, 'test.js') ],
1021cb0ef41Sopenharmony_ci                                           { encoding: 'utf8', env: env });
1031cb0ef41Sopenharmony_ci  assert.strictEqual(child.trim(), 'local');
1041cb0ef41Sopenharmony_ci}
105