1var common = require('../common-tap.js') 2 3var resolve = require('path').resolve 4var fs = require('graceful-fs') 5var test = require('tap').test 6var rimraf = require('rimraf') 7var Tacks = require('tacks') 8var File = Tacks.File 9var Dir = Tacks.Dir 10var Symlink = Tacks.Symlink 11var isWindows = require('../../lib/utils/is-windows.js') 12 13var base = common.pkg 14var fixture = new Tacks(Dir({ 15 'working-dir': Dir({ 16 'node_modules': Dir({}) // so it doesn't try to install into npm's own node_modules 17 }), 18 'test-module': Dir({ 19 'package.json': File({ 20 name: '@test/linked', 21 version: '1.0.0', 22 bin: { 23 linked: './index.js' 24 } 25 }), 26 'index.js': File("module.exports = function () { console.log('whoop whoop') }") 27 }), 28 'global-dir': Dir({}), 29 'linked-global-dir': Symlink('global-dir') 30})) 31 32var workingDir = resolve(base, 'working-dir') 33var toInstall = resolve(base, 'test-module') 34var linkedGlobal = resolve(base, 'linked-global-dir') 35 36var env = Object.assign({}, process.env) 37 38// We set the global install location via env var here 39// instead of passing it in via `--prefix` because 40// `--prefix` ALSO changes the current package location. 41// And we don't ue the PREFIX env var because 42// npm_config_prefix takes precedence over it and is 43// passed in when running from the npm test suite. 44env.npm_config_prefix = linkedGlobal 45var EXEC_OPTS = { 46 cwd: workingDir, 47 env: env, 48 stdio: [0, 'pipe', 2] 49} 50 51test('setup', function (t) { 52 cleanup() 53 setup() 54 55 t.end() 56}) 57 58test('install and link', function (t) { 59 var globalBin = resolve(linkedGlobal, isWindows ? '.' : 'bin', 'linked') 60 var globalModule = resolve(linkedGlobal, isWindows ? '.' : 'lib', 'node_modules', '@test', 'linked') 61 // link our test module into the global folder 62 return common.npm(['--loglevel', 'error', 'link', toInstall], EXEC_OPTS).spread((code, out) => { 63 t.comment(out) 64 t.is(code, 0, 'link succeeded') 65 var localBin = resolve(workingDir, 'node_modules', '.bin', 'linked') 66 var localModule = resolve(workingDir, 'node_modules', '@test', 'linked') 67 try { 68 t.ok(fs.statSync(globalBin), 'global bin exists') 69 t.is(fs.lstatSync(globalModule).isSymbolicLink(), true, 'global module is link') 70 t.ok(fs.statSync(localBin), 'local bin exists') 71 t.is(fs.lstatSync(localModule).isSymbolicLink(), true, 'local module is link') 72 } catch (ex) { 73 t.ifError(ex, 'linking happened') 74 } 75 if (code !== 0) throw new Error('aborting') 76 77 // and try removing it and make sure that succeeds 78 return common.npm(['--global', '--loglevel', 'error', 'rm', '@test/linked'], EXEC_OPTS) 79 }).spread((code, out) => { 80 t.comment(out) 81 t.is(code, 0, 'rm succeeded') 82 t.throws(function () { fs.statSync(globalBin) }, 'global bin removed') 83 t.throws(function () { fs.statSync(globalModule) }, 'global module removed') 84 }) 85}) 86 87test('cleanup', function (t) { 88 cleanup() 89 90 t.end() 91}) 92 93function cleanup () { 94 fixture.remove(base) 95 rimraf.sync(base) 96} 97 98function setup () { 99 fixture.create(base) 100} 101