2 var test = require('tap').test
3 var common = require('../common-tap.js')
4 var path = require('path')
5 var rimraf = require('rimraf')
6 var mkdirp = require('mkdirp')
7 var fs = require('graceful-fs')
8 var basepath = path.resolve(__dirname, path.basename(__filename, '.js'))
9 var fixturepath = path.resolve(basepath, 'npm-test-files')
10 var modulepath = path.resolve(basepath, 'node_modules')
11 var installedpath = path.resolve(modulepath, 'npm-test-files')
12 var Tacks = require('tacks')
16 test('basic file inclusion', function (t) {
17 var fixture = new Tacks(
19 'package.json': File({
20 name: 'npm-test-files',
28 sub: Dir({ include: File('') }),
32 withFixture(t, fixture, function (done) {
33 t.ok(fileExists('include'), 'toplevel file included')
34 t.ok(fileExists('sub/include'), 'nested file included')
35 t.notOk(fileExists('notincluded'), 'unspecified file not included')
40 test('basic file exclusion', function (t) {
41 var fixture = new Tacks(
43 'package.json': File({
44 name: 'npm-test-files',
53 sub: Dir({ ignore: File('') })
56 withFixture(t, fixture, function (done) {
57 t.notOk(fileExists('ignore'), 'toplevel file excluded')
58 t.notOk(fileExists('sub/ignore'), 'nested file excluded')
59 t.ok(fileExists('include'), 'unignored file included')
64 test('toplevel-only and blanket ignores', function (t) {
65 var fixture = new Tacks(
67 'package.json': File({
68 name: 'npm-test-files',
93 withFixture(t, fixture, function (done) {
94 t.notOk(fileExists('shallow2'), '/ file excluded')
95 t.ok(fileExists('sub/shallow1'), 'nested ./ file included')
96 t.ok(fileExists('sub/shallow2'), 'nested / file included')
97 t.ok(fileExists('sub/sub/onelevel'), 'double-nested file included')
98 t.notOk(fileExists('sub/onelevel'), 'nested / file excluded')
99 t.notOk(fileExists('deep'), 'deep file excluded')
100 t.notOk(fileExists('sub/deep'), 'nested deep file excluded')
101 t.notOk(fileExists('sub/sub/deep'), 'double-nested deep file excluded')
102 t.ok(fileExists('shallow1'), './ file included')
107 test('.npmignore works for nested directories recursively', function (t) {
108 var fixture = new Tacks(
110 'package.json': File({
111 name: 'npm-test-files',
136 withFixture(t, fixture, function (done) {
137 t.notOk(fileExists('ignore'), 'toplevel file excluded')
138 t.ok(fileExists('include'), 'unignored file included')
139 t.ok(fileExists('sub/ignore'), 'same-name file in nested dir included')
140 t.ok(fileExists('sub/include'), 'unignored nested dir file included')
141 t.notOk(fileExists('sub/sub/ignore'), 'sub-sub-directory file excluded')
142 t.ok(fileExists('sub/sub/include'), 'sub-sube-directory file included')
143 t.notOk(fileExists('deep'), 'deep file excluded')
144 t.notOk(fileExists('sub/deep'), 'sub-dir deep file excluded')
145 t.notOk(fileExists('sub/sub/deep'), 'sub-sub-dir deep file excluded')
150 test('.gitignore should have identical semantics', function (t) {
151 var fixture = new Tacks(
153 'package.json': File({
154 name: 'npm-test-files',
179 withFixture(t, fixture, function (done) {
180 t.notOk(fileExists('shallow2'), '/ file excluded')
181 t.ok(fileExists('sub/shallow1'), 'nested ./ file included')
182 t.ok(fileExists('sub/shallow2'), 'nested / file included')
183 t.ok(fileExists('sub/sub/onelevel'), 'double-nested file included')
184 t.notOk(fileExists('sub/onelevel'), 'nested / file excluded')
185 t.notOk(fileExists('deep'), 'deep file excluded')
186 t.notOk(fileExists('sub/deep'), 'nested deep file excluded')
187 t.notOk(fileExists('sub/sub/deep'), 'double-nested deep file excluded')
188 t.ok(fileExists('shallow1'), './ file included')
193 test('.npmignore should always be overridden by files array', function (t) {
194 var fixture = new Tacks(
196 'package.json': File({
197 name: 'npm-test-files',
216 withFixture(t, fixture, function (done) {
217 t.notOk(fileExists('ignore'), 'toplevel file excluded')
218 t.ok(fileExists('include'), 'unignored file included')
219 t.ok(fileExists('sub/include'), 'nested file included')
224 test('.gitignore supported for ignores', function (t) {
225 var fixture = new Tacks(
227 'package.json': File({
228 name: 'npm-test-files',
237 sub: Dir({ ignore: File('') })
240 withFixture(t, fixture, function (done) {
241 t.notOk(fileExists('ignore'), 'toplevel file excluded')
242 t.notOk(fileExists('sub/ignore'), 'nested file excluded')
243 t.ok(fileExists('include'), 'unignored file included')
248 test('.npmignore completely overrides .gitignore', function (t) {
249 var fixture = new Tacks(
251 'package.json': File({
252 name: 'npm-test-files',
265 sub: Dir({ include: File('') }),
269 withFixture(t, fixture, function (done) {
270 t.ok(fileExists('include'), 'gitignored toplevel file included')
271 t.ok(fileExists('extra'), 'gitignored extra toplevel file included')
272 t.ok(fileExists('sub/include'), 'gitignored nested file included')
273 t.notOk(fileExists('ignore'), 'toplevel file excluded')
274 t.notOk(fileExists('sub/ignore'), 'nested file excluded')
279 test('files array overrides .npmignore', function (t) {
280 var fixture = new Tacks(
282 'package.json': File({
283 name: 'npm-test-files',
295 sub: Dir({ include: File('') })
298 withFixture(t, fixture, function (done) {
299 t.ok(fileExists('include'), 'toplevel file included')
300 t.ok(fileExists('sub/include'), 'nested file included')
305 test('includes files regardless of emptiness', function (t) {
306 var fixture = new Tacks(
308 'package.json': File({
309 name: 'npm-test-files',
316 full: File('This file has contents~'),
320 withFixture(t, fixture, function (done) {
321 t.ok(fileExists('full'), 'contentful file included')
322 t.ok(fileExists('empty'), 'empty file included')
327 test('.npmignore itself gets included', function (t) {
328 var fixture = new Tacks(
330 'package.json': File({
331 name: 'npm-test-files',
337 '.npmignore': File('')
340 withFixture(t, fixture, function (done) {
341 t.ok(fileExists('.npmignore'), '.npmignore included')
346 test('include default files when missing files spec', function (t) {
347 var fixture = new Tacks(
349 'package.json': File({
350 name: 'npm-test-files',
353 'index.js': File(''),
355 node_modules: Dir({foo: Dir({bar: File('')})})
358 withFixture(t, fixture, function (done) {
359 t.ok(fileExists('index.js'), 'index.js included')
360 t.ok(fileExists('foo'), 'foo included')
361 t.notOk(fileExists('node_modules'), 'node_modules not included')
366 test('include main file', function (t) {
367 var fixture = new Tacks(
369 'package.json': File({
370 name: 'npm-test-files',
375 'index.js': File(''),
379 withFixture(t, fixture, function (done) {
380 t.ok(fileExists('foo.js'), 'foo.js included because of main')
381 t.notOk(fileExists('index.js'), 'index.js not included')
386 test('certain files ignored unconditionally', function (t) {
387 var fixture = new Tacks(
389 'package.json': File({
390 name: 'npm-test-files',
409 '.git': Dir({foo: File('')}),
410 '.svn': Dir({foo: File('')}),
411 'CVS': Dir({foo: File('')}),
412 '.hg': Dir({foo: File('')}),
413 '.lock-wscript': File(''),
414 '.wafpickle-0': File(''),
415 '.wafpickle-5': File(''),
416 '.wafpickle-50': File(''),
417 'build': Dir({'config.gypi': File('')}),
418 'npm-debug.log': File(''),
420 '.foo.swp': File(''),
421 '.DS_Store': Dir({foo: File('')}),
423 '._ohnoes': Dir({noes: File('')})
426 withFixture(t, fixture, function (done) {
427 t.notOk(fileExists('.git'), '.git not included')
428 t.notOk(fileExists('.svn'), '.svn not included')
429 t.notOk(fileExists('CVS'), 'CVS not included')
430 t.notOk(fileExists('.hg'), '.hg not included')
431 t.notOk(fileExists('.lock-wscript'), '.lock-wscript not included')
432 t.notOk(fileExists('.wafpickle-0'), '.wafpickle-0 not included')
433 t.notOk(fileExists('.wafpickle-5'), '.wafpickle-5 not included')
434 t.notOk(fileExists('.wafpickle-50'), '.wafpickle-50 not included')
435 t.notOk(fileExists('build/config.gypi'), 'build/config.gypi not included')
436 t.notOk(fileExists('npm-debug.log'), 'npm-debug.log not included')
437 t.notOk(fileExists('.npmrc'), '.npmrc not included')
438 t.notOk(fileExists('.foo.swp'), '.foo.swp not included')
439 t.notOk(fileExists('.DS_Store'), '.DS_Store not included')
440 t.notOk(fileExists('._ohno'), '._ohno not included')
441 t.notOk(fileExists('._ohnoes'), '._ohnoes not included')
446 test('certain files included unconditionally', function (t) {
447 var fixture = new Tacks(
449 'package.json': File({
450 name: 'npm-test-files',
469 'readme.md': File(''),
470 'readme.randomext': File(''),
471 'changelog': File(''),
472 'CHAngelog': File(''),
473 'ChangeLOG.txt': File(''),
480 withFixture(t, fixture, function (done) {
481 t.ok(fileExists('package.json'), 'package.json included')
482 t.ok(fileExists('README'), 'README included')
483 t.ok(fileExists('Readme'), 'Readme included')
484 t.ok(fileExists('readme.md'), 'readme.md included')
485 t.ok(fileExists('readme.randomext'), 'readme.randomext included')
486 t.ok(fileExists('changelog'), 'changelog included')
487 t.ok(fileExists('CHAngelog'), 'CHAngelog included')
488 t.ok(fileExists('ChangeLOG.txt'), 'ChangeLOG.txt included')
489 t.ok(fileExists('license'), 'license included')
490 t.ok(fileExists('licence'), 'licence included')
491 t.ok(fileExists('LICENSE'), 'LICENSE included')
492 t.ok(fileExists('LICENCE'), 'LICENCE included')
497 test('folder-based inclusion works', function (t) {
498 var fixture = new Tacks(
500 'package.json': File({
501 name: 'npm-test-files',
522 withFixture(t, fixture, function (done) {
523 t.ok(fileExists('sub1/sub/include1'), 'nested dir included')
524 t.ok(fileExists('sub1/sub/include2'), 'nested dir included')
525 t.notOk(fileExists('sub1/ignored'), 'unspecified file not included')
527 t.ok(fileExists('sub2/include1'), 'dir contents included')
528 t.ok(fileExists('sub2/include2'), 'dir contents included')
529 t.notOk(fileExists('sub2/empty'), 'empty dir not included')
535 function fileExists (file) {
537 return !!fs.statSync(path.resolve(installedpath, file))
543 function withFixture (t, fixture, tester) {
544 fixture.create(fixturepath)
545 mkdirp.sync(modulepath)
546 common.npm(['install', fixturepath], {cwd: basepath}, installCheckAndTest)
547 function installCheckAndTest (err, code) {
549 t.is(code, 0, 'install went ok')
550 tester(removeAndDone)
552 function removeAndDone (err) {
554 fixture.remove(fixturepath)
555 rimraf.sync(basepath)