1var mkdirp = require('mkdirp') 2var path = require('path') 3var test = require('tap').test 4var lstatSync = require('fs').lstatSync 5var writeFileSync = require('fs').writeFileSync 6 7var common = require('../common-tap.js') 8 9var link = path.join(common.pkg, 'link') 10var linkScoped = path.join(common.pkg, 'link-scoped') 11var linkInstall = path.join(common.pkg, 'link-install') 12var linkInside = path.join(linkInstall, 'node_modules', 'inside') 13var linkRoot = path.join(common.pkg, 'link-root') 14 15var config = 'prefix = ' + linkRoot 16var configPath = path.join(link, '_npmrc') 17 18var OPTS = { 19 env: { 20 'npm_config_userconfig': configPath 21 } 22} 23 24var readJSON = { 25 name: 'foo', 26 version: '1.0.0', 27 description: '', 28 main: 'index.js', 29 scripts: { 30 test: 'echo "Error: no test specified" && exit 1' 31 }, 32 author: '', 33 license: 'ISC' 34} 35 36var readScopedJSON = { 37 name: '@scope/foo', 38 version: '1.0.0', 39 description: '', 40 main: 'index.js', 41 scripts: { 42 test: 'echo "Error: no test specified" && exit 1' 43 }, 44 author: '', 45 license: 'ISC' 46} 47 48var installJSON = { 49 name: 'bar', 50 version: '1.0.0', 51 description: '', 52 main: 'index.js', 53 scripts: { 54 test: 'echo "Error: no test specified" && exit 1' 55 }, 56 author: '', 57 license: 'ISC' 58} 59 60var insideInstallJSON = { 61 name: 'inside', 62 version: '1.0.0', 63 description: '', 64 main: 'index.js', 65 scripts: { 66 test: 'echo "Error: no test specified" && exit 1' 67 }, 68 author: '', 69 license: 'ISC' 70} 71 72test('setup', function (t) { 73 mkdirp.sync(linkRoot) 74 mkdirp.sync(link) 75 writeFileSync( 76 path.join(link, 'package.json'), 77 JSON.stringify(readJSON, null, 2) 78 ) 79 mkdirp.sync(linkScoped) 80 writeFileSync( 81 path.join(linkScoped, 'package.json'), 82 JSON.stringify(readScopedJSON, null, 2) 83 ) 84 mkdirp.sync(linkInstall) 85 writeFileSync( 86 path.join(linkInstall, 'package.json'), 87 JSON.stringify(installJSON, null, 2) 88 ) 89 mkdirp.sync(linkInside) 90 writeFileSync( 91 path.join(linkInside, 'package.json'), 92 JSON.stringify(insideInstallJSON, null, 2) 93 ) 94 writeFileSync(configPath, config) 95 common.npm(['ls', '-g', '--depth=0'], OPTS, function (err, c, out) { 96 t.ifError(err) 97 t.equal(c, 0, 'set up ok') 98 t.notOk(out.match(/UNMET DEPENDENCY foo@/), "foo isn't in global") 99 t.end() 100 }) 101}) 102 103test('create global link', function (t) { 104 process.chdir(link) 105 common.npm(['link'], OPTS, function (err, c, out) { 106 t.ifError(err, 'link has no error') 107 common.npm(['ls', '-g'], OPTS, function (err, c, out, stderr) { 108 t.ifError(err) 109 t.equal(c, 0) 110 t.equal(stderr, '', 'got expected stderr') 111 t.has(out, /foo@1.0.0/, 'creates global link ok') 112 t.end() 113 }) 114 }) 115}) 116 117test('create global inside link', function (t) { 118 process.chdir(linkInside) 119 common.npm(['link'], OPTS, function (err, c, out) { 120 t.ifError(err, 'link has no error') 121 common.npm(['ls', '-g'], OPTS, function (err, c, out, stderr) { 122 t.ifError(err) 123 t.equal(c, 0) 124 t.equal(stderr, '', 'got expected stderr') 125 t.has(out, /inside@1.0.0/, 'creates global inside link ok') 126 t.end() 127 }) 128 }) 129}) 130 131test('create scoped global link', function (t) { 132 process.chdir(linkScoped) 133 common.npm(['link'], OPTS, function (err, c, out) { 134 t.ifError(err, 'link has no error') 135 common.npm(['ls', '-g'], OPTS, function (err, c, out, stderr) { 136 t.ifError(err) 137 t.equal(c, 0) 138 t.equal(stderr, '', 'got expected stderr') 139 t.has(out, /@scope[/]foo@1.0.0/, 'creates global link ok') 140 t.end() 141 }) 142 }) 143}) 144 145test('link-install the package', function (t) { 146 process.chdir(linkInstall) 147 common.npm(['link', 'foo'], OPTS, function (err) { 148 t.ifError(err, 'link-install has no error') 149 common.npm(['ls'], OPTS, function (err, c, out) { 150 t.ifError(err) 151 t.equal(c, 1) 152 t.has(out, /foo@1.0.0/, 'link-install ok') 153 t.end() 154 }) 155 }) 156}) 157 158test('link-inside-install fails', function (t) { 159 process.chdir(linkInstall) 160 t.notOk(lstatSync(linkInside).isSymbolicLink(), 'directory for linked package is not a symlink to begin with') 161 common.npm(['link', 'inside'], OPTS, function (err, code) { 162 t.ifError(err, 'npm removed the linked package without error') 163 t.notEqual(code, 0, 'link operation failed') 164 t.notOk(lstatSync(linkInside).isSymbolicLink(), 'directory for linked package has not turned into a symlink') 165 t.end() 166 }) 167}) 168 169test('link-install the scoped package', function (t) { 170 process.chdir(linkInstall) 171 common.npm(['link', linkScoped], OPTS, function (err) { 172 t.ifError(err, 'link-install has no error') 173 common.npm(['ls'], OPTS, function (err, c, out) { 174 t.ifError(err) 175 t.equal(c, 1) 176 t.has(out, /@scope[/]foo@1.0.0/, 'link-install ok') 177 t.end() 178 }) 179 }) 180}) 181 182test('ls the linked packages', function (t) { 183 process.chdir(linkInstall) 184 common.npm(['ls', '--link'], OPTS, function (err, c, out) { 185 t.ifError(err, 'ls --link did not have an error') 186 t.equal(c, 1) 187 t.has(out, /@scope\/foo@1\.0\.0 ->/, 'output contains scoped link') 188 t.has(out, /foo@1\.0\.0 ->/, 'output contains link') 189 t.doesNotHave(out, /inside@1\.0\.0/, 'output does not contain unlinked dependency') 190 t.end() 191 }) 192}) 193 194test('cleanup', function (t) { 195 process.chdir(common.pkg) 196 common.npm(['rm', 'foo'], OPTS, function (err, code) { 197 t.ifError(err, 'npm removed the linked package without error') 198 t.equal(code, 0, 'cleanup foo in local ok') 199 common.npm(['rm', '-g', 'foo'], OPTS, function (err, code) { 200 t.ifError(err, 'npm removed the global package without error') 201 t.equal(code, 0, 'cleanup foo in global ok') 202 t.end() 203 }) 204 }) 205}) 206