diff --git a/scripts/update-snapshots.js b/scripts/update-snapshots.js index b7e9ee3223a..79b6e28fde8 100755 --- a/scripts/update-snapshots.js +++ b/scripts/update-snapshots.js @@ -1,7 +1,8 @@ #!/usr/bin/env node +const { readdirSync } = require('fs'); const { resolve, join } = require('path'); -const { readdirSync, copydirSync, copyFileSync, rimrafSync } = require('sander'); +const { copySync, removeSync } = require('fs-extra'); const basePath = resolve(__dirname, '../test'); @@ -14,10 +15,10 @@ for (const dir of formDirsToHandle) { formDirsToHandle.push(...testFiles.map(filename => join(dir, filename))); } else if (testFiles.includes('_actual')) { const expectedPath = join(testPath, '_expected'); - rimrafSync(expectedPath); - copydirSync(join(testPath, '_actual')).to(expectedPath); + removeSync(expectedPath); + copySync(join(testPath, '_actual'), expectedPath); } else if (testFiles.includes('_actual.js')) { - copyFileSync(join(testPath, '_actual.js')).to(join(testPath, '_expected.js')); + copySync(join(testPath, '_actual.js'), join(testPath, '_expected.js')); } else { throw new Error(`Could not find test output in ${testPath}`); } @@ -32,8 +33,8 @@ for (const dir of chunkingDirsToHandle) { chunkingDirsToHandle.push(...testFiles.map(filename => join(dir, filename))); } else if (testFiles.includes('_actual')) { const expectedPath = join(testPath, '_expected'); - rimrafSync(expectedPath); - copydirSync(join(testPath, '_actual')).to(expectedPath); + removeSync(expectedPath); + copySync(join(testPath, '_actual'), expectedPath); } else { throw new Error(`Could not find test output in ${testPath}`); } diff --git a/test/cli/index.js b/test/cli/index.js index d175968f6ed..ae86845fde6 100644 --- a/test/cli/index.js +++ b/test/cli/index.js @@ -1,8 +1,9 @@ const assert = require('assert'); const { exec } = require('child_process'); const { existsSync, readFileSync } = require('fs'); -const path = require('path'); -const sander = require('sander'); +const { basename, resolve, sep } = require('path'); +const process = require('process'); +const { copySync, removeSync, statSync } = require('fs-extra'); const { normaliseOutput, runTestSuiteWithSamples, @@ -11,22 +12,22 @@ const { const cwd = process.cwd(); -sander.rimrafSync(__dirname, 'node_modules'); -sander.copydirSync(__dirname, 'node_modules_rename_me').to(__dirname, 'node_modules'); +removeSync(resolve(__dirname, 'node_modules')); +copySync(resolve(__dirname, 'node_modules_rename_me'), resolve(__dirname, 'node_modules')); runTestSuiteWithSamples( 'cli', - path.resolve(__dirname, 'samples'), + resolve(__dirname, 'samples'), (dir, config) => { (config.skip ? it.skip : config.solo ? it.only : it)( - path.basename(dir) + ': ' + config.description, + basename(dir) + ': ' + config.description, done => { process.chdir(config.cwd || dir); if (config.before) config.before(); const command = config.command.replace( /(^| )rollup($| )/g, - `node ${path.resolve(__dirname, '../../dist/bin')}${path.sep}rollup ` + `node ${resolve(__dirname, '../../dist/bin')}${sep}rollup ` ); const childProcess = exec( @@ -99,7 +100,7 @@ runTestSuiteWithSamples( } catch (err) { done(err); } - } else if (existsSync('_expected') && sander.statSync('_expected').isDirectory()) { + } else if (existsSync('_expected') && statSync('_expected').isDirectory()) { try { assertDirectoriesAreEqual('_actual', '_expected'); done(); diff --git a/test/watch/index.js b/test/watch/index.js index 2ee8a207520..bf873cd4dab 100644 --- a/test/watch/index.js +++ b/test/watch/index.js @@ -7,8 +7,8 @@ const { unlinkSync, writeFileSync } = require('fs'); -const path = require('path'); -const { removeSync } = require('fs-extra'); +const { resolve } = require('path'); +const { copy, removeSync } = require('fs-extra'); const sander = require('sander'); const rollup = require('../../dist/rollup'); @@ -83,111 +83,105 @@ describe('rollup.watch', () => { it('watches a file and triggers reruns if necessary', () => { let triggerRestart = false; - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - plugins: { - options(options) { - assert.strictEqual(this.meta.watchMode, true, 'watchMode in options'); - }, - transform(code) { - assert.strictEqual(this.meta.watchMode, true, 'watchMode in transform'); - if (triggerRestart) { - triggerRestart = false; - return wait(100) - .then(() => writeFileSync('test/_tmp/input/main.js', 'export default 44;')) - .then(() => wait(100)) - .then(() => code); - } - } - }, - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - triggerRestart = true; - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + options(options) { + assert.strictEqual(this.meta.watchMode, true, 'watchMode in options'); }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 44); + transform(code) { + assert.strictEqual(this.meta.watchMode, true, 'watchMode in transform'); + if (triggerRestart) { + triggerRestart = false; + return wait(100) + .then(() => writeFileSync('test/_tmp/input/main.js', 'export default 44;')) + .then(() => wait(100)) + .then(() => code); + } } - ]); + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + triggerRestart = true; + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 44); + } + ]); + }); }); it('does not fail for virtual files', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - plugins: { - resolveId(id) { - if (id === 'virtual') { - return id; - } - }, - load(id) { - if (id === 'virtual') { - return `export const value = 42;`; - } + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + resolveId(id) { + if (id === 'virtual') { + return id; } }, - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - writeFileSync( - 'test/_tmp/input/main.js', - "import {value} from 'virtual';\nexport default value + 1;" - ); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + load(id) { + if (id === 'virtual') { + return `export const value = 42;`; + } } - ]); + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + writeFileSync( + 'test/_tmp/input/main.js', + "import {value} from 'virtual';\nexport default value + 1;" + ); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); }); it('passes file events to the watchChange plugin hook once for each change', async () => { let watchChangeCnt = 0; - await sander.copydir('test/watch/samples/basic').to('test/_tmp/input'); + await copy('test/watch/samples/basic', 'test/_tmp/input'); await wait(100); watcher = rollup.watch({ input: 'test/_tmp/input/main.js', @@ -199,7 +193,7 @@ describe('rollup.watch', () => { plugins: { watchChange(id) { watchChangeCnt++; - assert.strictEqual(id, path.resolve('test/_tmp/input/main.js')); + assert.strictEqual(id, resolve('test/_tmp/input/main.js')); } } }); @@ -244,11 +238,11 @@ describe('rollup.watch', () => { }); it('passes change parameter to the watchChange plugin hook', async () => { - const WATCHED_ID = path.resolve('test/_tmp/input/watched'); + const WATCHED_ID = resolve('test/_tmp/input/watched'); const events = []; let ids; - const expectedIds = [WATCHED_ID, path.resolve('test/_tmp/input/main.js')]; - await sander.copydir('test/watch/samples/watch-files').to('test/_tmp/input'); + const expectedIds = [WATCHED_ID, resolve('test/_tmp/input/main.js')]; + await copy('test/watch/samples/watch-files', 'test/_tmp/input'); await promises.unlink(WATCHED_ID); await wait(100); watcher = rollup.watch({ @@ -316,10 +310,10 @@ describe('rollup.watch', () => { }); it('correctly rewrites change event during build delay', async () => { - const WATCHED_ID = path.resolve('test/_tmp/input/watched'); - const MAIN_ID = path.resolve('test/_tmp/input/main.js'); + const WATCHED_ID = resolve('test/_tmp/input/watched'); + const MAIN_ID = resolve('test/_tmp/input/main.js'); let lastEvent = null; - await sander.copydir('test/watch/samples/watch-files').to('test/_tmp/input'); + await copy('test/watch/samples/watch-files', 'test/_tmp/input'); await wait(100); watcher = rollup.watch({ input: 'test/_tmp/input/main.js', @@ -395,589 +389,545 @@ describe('rollup.watch', () => { let calls = 0; let ctx1; let ctx2; - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: [ + { + buildStart() { + ctx1 = this; + }, + closeWatcher() { + assert.strictEqual(ctx1, this); + calls++; + } }, - plugins: [ - { - buildStart() { - ctx1 = this; - }, - closeWatcher() { - assert.strictEqual(ctx1, this); - calls++; - } + { + buildStart() { + ctx2 = this; }, - { - buildStart() { - ctx2 = this; - }, - closeWatcher() { - assert.strictEqual(ctx2, this); - calls++; - } + closeWatcher() { + assert.strictEqual(ctx2, this); + calls++; } - ] - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - assert.ok(ctx1); - assert.ok(ctx2); - watcher.once('close', () => { - assert.strictEqual(calls, 2); - }); - watcher.close(); } - ]); + ] }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + assert.ok(ctx1); + assert.ok(ctx2); + watcher.once('close', () => { + assert.strictEqual(calls, 2); + }); + watcher.close(); + } + ]); + }); }); it('watches a file in code-splitting mode', () => { - return sander - .copydir('test/watch/samples/code-splitting') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: ['test/_tmp/input/main1.js', 'test/_tmp/input/main2.js'], - output: { - dir: 'test/_tmp/output', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/main1.js'), 21); - assert.strictEqual(run('../_tmp/output/main2.js'), 42); - writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/main1.js'), 22); - assert.strictEqual(run('../_tmp/output/main2.js'), 44); - } - ]); + return copy('test/watch/samples/code-splitting', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: ['test/_tmp/input/main1.js', 'test/_tmp/input/main2.js'], + output: { + dir: 'test/_tmp/output', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/main1.js'), 21); + assert.strictEqual(run('../_tmp/output/main2.js'), 42); + writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/main1.js'), 22); + assert.strictEqual(run('../_tmp/output/main2.js'), 44); + } + ]); + }); }); it('watches a file in code-splitting mode with an input object', () => { - return sander - .copydir('test/watch/samples/code-splitting') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: { - _main_1: 'test/_tmp/input/main1.js', - 'subfolder/_main_2': 'test/_tmp/input/main2.js' - }, - output: { - dir: 'test/_tmp/output', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/_main_1.js'), 21); - assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 42); - writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/_main_1.js'), 22); - assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 44); - } - ]); + return copy('test/watch/samples/code-splitting', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: { + _main_1: 'test/_tmp/input/main1.js', + 'subfolder/_main_2': 'test/_tmp/input/main2.js' + }, + output: { + dir: 'test/_tmp/output', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/_main_1.js'), 21); + assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 42); + writeFileSync('test/_tmp/input/shared.js', 'export const value = 22;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/_main_1.js'), 22); + assert.strictEqual(run('../_tmp/output/subfolder/_main_2.js'), 44); + } + ]); + }); }); it('recovers from an error', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - writeFileSync('test/_tmp/input/main.js', 'export nope;'); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - } - ]); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); - }); - it('recovers from an error on initial build', () => { - return sander - .copydir('test/watch/samples/error') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + writeFileSync('test/_tmp/input/main.js', 'export nope;'); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); + }); - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - } - ]); + it('recovers from an error on initial build', () => { + return copy('test/watch/samples/error', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); }); it('recovers from a plugin error on initial build', () => { let count = 0; - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - plugins: { - transform() { - if (count++ === 0) { - this.error('The first run failed, try again.'); - } + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + transform() { + if (count++ === 0) { + this.error('The first run failed, try again.'); } - }, - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); } - ]); + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); }); it('recovers from an error even when erroring entry was "renamed" (#38)', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - unlinkSync('test/_tmp/input/main.js'); - writeFileSync('test/_tmp/input/main.js', 'export nope;'); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - unlinkSync('test/_tmp/input/main.js'); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - } - ]); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + unlinkSync('test/_tmp/input/main.js'); + writeFileSync('test/_tmp/input/main.js', 'export nope;'); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + unlinkSync('test/_tmp/input/main.js'); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); }); it('recovers from an error even when erroring dependency was "renamed" (#38)', () => { - return sander - .copydir('test/watch/samples/dependency') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - unlinkSync('test/_tmp/input/dep.js'); - writeFileSync('test/_tmp/input/dep.js', 'export nope;'); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - () => { - unlinkSync('test/_tmp/input/dep.js'); - writeFileSync('test/_tmp/input/dep.js', 'export const value = 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 44); - } - ]); + return copy('test/watch/samples/dependency', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + unlinkSync('test/_tmp/input/dep.js'); + writeFileSync('test/_tmp/input/dep.js', 'export nope;'); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + () => { + unlinkSync('test/_tmp/input/dep.js'); + writeFileSync('test/_tmp/input/dep.js', 'export const value = 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 44); + } + ]); + }); }); it('handles closing the watcher during a build', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - plugins: { - load() { - watcher.close(); - } - }, - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - const events = []; - watcher.on('event', event => events.push(event.code)); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - () => { - writeFileSync('test/_tmp/input/main.js', 'export default 44;'); - return wait(400).then(() => assert.deepStrictEqual(events, ['START', 'BUNDLE_START'])); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + load() { + watcher.close(); } - ]); + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + const events = []; + watcher.on('event', event => events.push(event.code)); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + () => { + writeFileSync('test/_tmp/input/main.js', 'export default 44;'); + return wait(400).then(() => assert.deepStrictEqual(events, ['START', 'BUNDLE_START'])); + } + ]); + }); }); it('handles closing the watcher during a build even if an error occurred', () => { - return sander - .copydir('test/watch/samples/error') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - plugins: { - load() { - watcher.close(); - } - }, - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - const events = []; - watcher.on('event', event => events.push(event.code)); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - () => { - writeFileSync('test/_tmp/input/main.js', 'export default 44;'); - return wait(400).then(() => assert.deepStrictEqual(events, ['START', 'BUNDLE_START'])); + return copy('test/watch/samples/error', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + plugins: { + load() { + watcher.close(); } - ]); + }, + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); - }); + const events = []; + watcher.on('event', event => events.push(event.code)); - it('stops watching files that are no longer part of the graph', () => { - return sander - .copydir('test/watch/samples/dependency') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + () => { + writeFileSync('test/_tmp/input/main.js', 'export default 44;'); + return wait(400).then(() => assert.deepStrictEqual(events, ['START', 'BUNDLE_START'])); + } + ]); + }); + }); - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - writeFileSync('test/_tmp/input/main.js', 'export default 42;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - writeFileSync('test/_tmp/input/dep.js', '= invalid'); - return wait(400).then(() => assert.strictEqual(unexpectedEvent, false)); - } - ]); + it('stops watching files that are no longer part of the graph', () => { + return copy('test/watch/samples/dependency', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + writeFileSync('test/_tmp/input/main.js', 'export default 42;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + let unexpectedEvent = false; + watcher.once('event', event => { + unexpectedEvent = event; + }); + writeFileSync('test/_tmp/input/dep.js', '= invalid'); + return wait(400).then(() => assert.strictEqual(unexpectedEvent, false)); + } + ]); + }); }); it('refuses to watch the output file (#15)', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - writeFileSync('test/_tmp/input/main.js', `import '../output/bundle.js'`); - }, - 'START', - 'BUNDLE_START', - 'ERROR', - event => { - assert.strictEqual(event.error.message, 'Cannot import the generated bundle'); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - } - ]); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + writeFileSync('test/_tmp/input/main.js', `import '../output/bundle.js'`); + }, + 'START', + 'BUNDLE_START', + 'ERROR', + event => { + assert.strictEqual(event.error.message, 'Cannot import the generated bundle'); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); }); it('ignores files that are not specified in options.watch.include, if given', () => { - return sander - .copydir('test/watch/samples/ignored') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - watch: { - include: ['test/_tmp/input/+(main|foo).js'] - } - }); + return copy('test/watch/samples/ignored', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + watch: { + include: ['test/_tmp/input/+(main|foo).js'] + } + }); - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-1', - bar: 'bar-1' - }); - writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-1', + bar: 'bar-1' + }); + writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-2', + bar: 'bar-1' + }); + let unexpectedEvent = false; + watcher.once('event', event => { + unexpectedEvent = event; + }); + writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); + return wait(400).then(() => { assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { foo: 'foo-2', bar: 'bar-1' }); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); - return wait(400).then(() => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-2', - bar: 'bar-1' - }); - assert.strictEqual(unexpectedEvent, false); - }); - } - ]); - }); + assert.strictEqual(unexpectedEvent, false); + }); + } + ]); + }); }); it('ignores files that are specified in options.watch.exclude, if given', () => { - return sander - .copydir('test/watch/samples/ignored') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - watch: { - exclude: ['test/_tmp/input/bar.js'] - } - }); + return copy('test/watch/samples/ignored', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + watch: { + exclude: ['test/_tmp/input/bar.js'] + } + }); - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-1', - bar: 'bar-1' - }); - writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-1', + bar: 'bar-1' + }); + writeFileSync('test/_tmp/input/foo.js', `export default 'foo-2';`); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { + foo: 'foo-2', + bar: 'bar-1' + }); + let unexpectedEvent = false; + watcher.once('event', event => { + unexpectedEvent = event; + }); + writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); + return wait(400).then(() => { assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { foo: 'foo-2', bar: 'bar-1' }); - let unexpectedEvent = false; - watcher.once('event', event => { - unexpectedEvent = event; - }); - writeFileSync('test/_tmp/input/bar.js', "export default 'bar-2';"); - return wait(400).then(() => { - assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { - foo: 'foo-2', - bar: 'bar-1' - }); - assert.strictEqual(unexpectedEvent, false); - }); - } - ]); - }); + assert.strictEqual(unexpectedEvent, false); + }); + } + ]); + }); }); it('only rebuilds the appropriate configs', () => { - return sander - .copydir('test/watch/samples/multiple') - .to('test/_tmp/input') + return copy('test/watch/samples/multiple', 'test/_tmp/input') .then(() => wait(100)) .then(() => { watcher = rollup.watch([ @@ -1024,9 +974,7 @@ describe('rollup.watch', () => { }); it('allows watching only some configs', () => { - return sander - .copydir('test/watch/samples/multiple') - .to('test/_tmp/input') + return copy('test/watch/samples/multiple', 'test/_tmp/input') .then(() => wait(100)) .then(() => { watcher = rollup.watch([ @@ -1055,14 +1003,8 @@ describe('rollup.watch', () => { 'BUNDLE_END', 'END', () => { - assert.strictEqual( - existsSync(path.resolve(__dirname, '../_tmp/output/bundle1.js')), - false - ); - assert.strictEqual( - existsSync(path.resolve(__dirname, '../_tmp/output/bundle2.js')), - true - ); + assert.strictEqual(existsSync(resolve(__dirname, '../_tmp/output/bundle1.js')), false); + assert.strictEqual(existsSync(resolve(__dirname, '../_tmp/output/bundle2.js')), true); assert.deepStrictEqual(run('../_tmp/output/bundle2.js'), 43); } ]); @@ -1070,132 +1012,123 @@ describe('rollup.watch', () => { }); it('respects output.globals', () => { - return sander - .copydir('test/watch/samples/globals') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'iife', - globals: { - jquery: 'jQuery' - } - }, - external: ['jquery'] - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - const generated = readFileSync('test/_tmp/output/bundle.js', 'utf8'); - assert.ok(/jQuery/.test(generated)); + return copy('test/watch/samples/globals', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'iife', + globals: { + jquery: 'jQuery' } - ]); + }, + external: ['jquery'] }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + const generated = readFileSync('test/_tmp/output/bundle.js', 'utf8'); + assert.ok(/jQuery/.test(generated)); + } + ]); + }); }); it('treats filenames literally, not as globs', () => { - return sander - .copydir('test/watch/samples/non-glob') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - writeFileSync('test/_tmp/input/[foo]/bar.js', `export const bar = 43;`); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 43); - } - ]); + return copy('test/watch/samples/non-glob', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + writeFileSync('test/_tmp/input/[foo]/bar.js', `export const bar = 43;`); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 43); + } + ]); + }); }); it('updates the right hashes on dependency changes', () => { let dynamicName; let staticName; let chunkName; - return sander - .copydir('test/watch/samples/hashing') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: ['test/_tmp/input/main-static.js', 'test/_tmp/input/main-dynamic.js'], - output: { - dir: 'test/_tmp/output', - format: 'cjs', - exports: 'auto', - entryFileNames: '[name].[hash].js', - chunkFileNames: '[name].[hash].js' - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - [dynamicName, staticName, chunkName] = readdirSync('test/_tmp/output').sort(); - removeSync('test/_tmp/output'); - - // this should only update the hash of that particular entry point - writeFileSync( - 'test/_tmp/input/main-static.js', - "import {value} from './shared';\nexport default 2 * value;" - ); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - const [newDynamicName, newStaticName, newChunkName] = - readdirSync('test/_tmp/output').sort(); - removeSync('test/_tmp/output'); - assert.notEqual(newStaticName, staticName); - assert.strictEqual(newDynamicName, dynamicName); - assert.strictEqual(newChunkName, chunkName); - staticName = newStaticName; - - // this should update all hashes - writeFileSync('test/_tmp/input/shared.js', 'export const value = 42;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - const [newDynamicName, newStaticName, newChunkName] = - readdirSync('test/_tmp/output').sort(); - assert.notEqual(newStaticName, staticName); - assert.notEqual(newDynamicName, dynamicName); - assert.notEqual(newChunkName, chunkName); - } - ]); + return copy('test/watch/samples/hashing', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: ['test/_tmp/input/main-static.js', 'test/_tmp/input/main-dynamic.js'], + output: { + dir: 'test/_tmp/output', + format: 'cjs', + exports: 'auto', + entryFileNames: '[name].[hash].js', + chunkFileNames: '[name].[hash].js' + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + [dynamicName, staticName, chunkName] = readdirSync('test/_tmp/output').sort(); + removeSync('test/_tmp/output'); + + // this should only update the hash of that particular entry point + writeFileSync( + 'test/_tmp/input/main-static.js', + "import {value} from './shared';\nexport default 2 * value;" + ); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + const [newDynamicName, newStaticName, newChunkName] = + readdirSync('test/_tmp/output').sort(); + removeSync('test/_tmp/output'); + assert.notEqual(newStaticName, staticName); + assert.strictEqual(newDynamicName, dynamicName); + assert.strictEqual(newChunkName, chunkName); + staticName = newStaticName; + + // this should update all hashes + writeFileSync('test/_tmp/input/shared.js', 'export const value = 42;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + const [newDynamicName, newStaticName, newChunkName] = + readdirSync('test/_tmp/output').sort(); + assert.notEqual(newStaticName, staticName); + assert.notEqual(newDynamicName, dynamicName); + assert.notEqual(newChunkName, chunkName); + } + ]); + }); }); it('runs transforms again on previously erroring files that were changed back', () => { @@ -1252,72 +1185,69 @@ describe('rollup.watch', () => { it('skips filesystem writes when configured', () => { let watchChangeCnt = 0; - return sander - .copydir('test/watch/samples/skip-writes') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - watch: { - skipWrite: true - }, - plugins: { - watchChange(id) { - watchChangeCnt++; - assert.strictEqual(id, path.resolve('test/_tmp/input/main.js')); - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - watchChangeCnt = 0; - assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); - assert.strictEqual(watchChangeCnt, 1); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); - assert.strictEqual(watchChangeCnt, 2); - writeFileSync('test/_tmp/input/main.js', 'export default 43;'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - // 'END', - evt => { - assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); - assert.strictEqual(watchChangeCnt, 3); - // still aware of its output destination - assert.strictEqual(evt.output[0], path.resolve('test/_tmp/output/bundle.js')); + return copy('test/watch/samples/skip-writes', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + watch: { + skipWrite: true + }, + plugins: { + watchChange(id) { + watchChangeCnt++; + assert.strictEqual(id, resolve('test/_tmp/input/main.js')); } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + watchChangeCnt = 0; + assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); + assert.strictEqual(watchChangeCnt, 1); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); + assert.strictEqual(watchChangeCnt, 2); + writeFileSync('test/_tmp/input/main.js', 'export default 43;'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + // 'END', + evt => { + assert.strictEqual(existsSync('../_tmp/output/bundle.js'), false); + assert.strictEqual(watchChangeCnt, 3); + // still aware of its output destination + assert.strictEqual(evt.output[0], resolve('test/_tmp/output/bundle.js')); + } + ]); + }); }); it('rebuilds immediately by default', async () => { - await sander.copydir('test/watch/samples/basic').to('test/_tmp/input'); + await copy('test/watch/samples/basic', 'test/_tmp/input'); watcher = rollup.watch({ input: 'test/_tmp/input/main.js', output: { @@ -1355,7 +1285,7 @@ describe('rollup.watch', () => { }); it('observes configured build delays', async () => { - await sander.copydir('test/watch/samples/basic').to('test/_tmp/input'); + await copy('test/watch/samples/basic', 'test/_tmp/input'); watcher = rollup.watch( [ { @@ -1435,356 +1365,333 @@ describe('rollup.watch', () => { describe('addWatchFile', () => { it('supports adding additional watch files in plugin hooks', () => { const watchChangeIds = new Set(); - const buildStartFile = path.resolve('test/_tmp/input/buildStart'); - const loadFile = path.resolve('test/_tmp/input/load'); - const resolveIdFile = path.resolve('test/_tmp/input/resolveId'); - const transformFile = path.resolve('test/_tmp/input/transform'); + const buildStartFile = resolve('test/_tmp/input/buildStart'); + const loadFile = resolve('test/_tmp/input/load'); + const resolveIdFile = resolve('test/_tmp/input/resolveId'); + const transformFile = resolve('test/_tmp/input/transform'); const watchFiles = [buildStartFile, loadFile, resolveIdFile, transformFile]; - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - for (const file of watchFiles) writeFileSync(file, 'initial'); - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + for (const file of watchFiles) writeFileSync(file, 'initial'); + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + buildStart() { + this.addWatchFile(buildStartFile); }, - plugins: { - buildStart() { - this.addWatchFile(buildStartFile); - }, - load() { - this.addWatchFile(loadFile); - }, - resolveId() { - this.addWatchFile(resolveIdFile); - }, - transform() { - this.addWatchFile(transformFile); - }, - watchChange(id) { - watchChangeIds.add(id); - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - // sometimes the watcher is triggered during the initial run - watchChangeIds.clear(); - for (const file of watchFiles) writeFileSync(file, 'changed'); + load() { + this.addWatchFile(loadFile); }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 42); - assert.deepStrictEqual([...watchChangeIds].sort(), watchFiles.sort()); + resolveId() { + this.addWatchFile(resolveIdFile); + }, + transform() { + this.addWatchFile(transformFile); + }, + watchChange(id) { + watchChangeIds.add(id); } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + // sometimes the watcher is triggered during the initial run + watchChangeIds.clear(); + for (const file of watchFiles) writeFileSync(file, 'changed'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 42); + assert.deepStrictEqual([...watchChangeIds].sort(), watchFiles.sort()); + } + ]); + }); }); it('respects changed watched files in the load hook', () => { - const WATCHED_ID = path.resolve('test/_tmp/input/watched'); - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - plugins: { - load() { - this.addWatchFile(WATCHED_ID); - return `export default "${readFileSync(WATCHED_ID, 'utf8').trim()}"`; - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); - writeFileSync(WATCHED_ID, 'next'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); + const WATCHED_ID = resolve('test/_tmp/input/watched'); + return copy('test/watch/samples/watch-files', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + load() { + this.addWatchFile(WATCHED_ID); + return `export default "${readFileSync(WATCHED_ID, 'utf8').trim()}"`; } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); + writeFileSync(WATCHED_ID, 'next'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); + } + ]); + }); }); it('respects changed watched files in the transform hook and removes them if they are no longer watched', () => { - const WATCHED_ID = path.resolve('test/_tmp/input/watched'); + const WATCHED_ID = resolve('test/_tmp/input/watched'); let addWatchFile = true; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' + return copy('test/watch/samples/watch-files', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + resolveId(id) { + if (id === 'dep') { + return id; + } }, - plugins: { - resolveId(id) { - if (id === 'dep') { - return id; - } - }, - load(id) { - if (id === 'dep') { - return `throw new Error('This should not be executed);`; - } - }, - transform(code, id) { - if (id.endsWith('main.js')) { - return `export { value as default } from 'dep';`; - } else { - if (addWatchFile) { - this.addWatchFile(WATCHED_ID); - } - return `export const value = "${readFileSync(WATCHED_ID, 'utf8').trim()}"`; - } + load(id) { + if (id === 'dep') { + return `throw new Error('This should not be executed);`; } - } - }); - const events = []; - watcher.on('event', event => events.push(event.code)); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); - addWatchFile = false; - writeFileSync(WATCHED_ID, 'next'); }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); - writeFileSync(WATCHED_ID, 'other'); - events.length = 0; - return wait(400).then(() => assert.deepStrictEqual(events, [])); + transform(code, id) { + if (id.endsWith('main.js')) { + return `export { value as default } from 'dep';`; + } else { + if (addWatchFile) { + this.addWatchFile(WATCHED_ID); + } + return `export const value = "${readFileSync(WATCHED_ID, 'utf8').trim()}"`; + } } - ]); + } }); + const events = []; + watcher.on('event', event => events.push(event.code)); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 'initial'); + addWatchFile = false; + writeFileSync(WATCHED_ID, 'next'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), 'next'); + writeFileSync(WATCHED_ID, 'other'); + events.length = 0; + return wait(400).then(() => assert.deepStrictEqual(events, [])); + } + ]); + }); }); it('respects changed watched modules that are already part of the graph in the transform hook', () => { - return sander - .copydir('test/watch/samples/dependencies') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - plugins: { - transform(code, id) { - if (id.endsWith('dep1.js')) { - this.addWatchFile(path.resolve('test/_tmp/input/dep2.js')); - const text = readFileSync('test/_tmp/input/dep2.js', 'utf8').trim(); - return `export default ${JSON.stringify(text)}`; - } + return copy('test/watch/samples/dependencies', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + transform(code, id) { + if (id.endsWith('dep1.js')) { + this.addWatchFile(resolve('test/_tmp/input/dep2.js')); + const text = readFileSync('test/_tmp/input/dep2.js', 'utf8').trim(); + return `export default ${JSON.stringify(text)}`; } } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual( - run('../_tmp/output/bundle.js'), - `dep1: "export default 'dep2';", dep2: "dep2"` - ); - writeFileSync('test/_tmp/input/dep2.js', 'export default "next";'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual( - run('../_tmp/output/bundle.js'), - `dep1: "export default "next";", dep2: "next"` - ); - } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual( + run('../_tmp/output/bundle.js'), + `dep1: "export default 'dep2';", dep2: "dep2"` + ); + writeFileSync('test/_tmp/input/dep2.js', 'export default "next";'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual( + run('../_tmp/output/bundle.js'), + `dep1: "export default "next";", dep2: "next"` + ); + } + ]); + }); }); it('respects changed watched directories in the transform hook', () => { - const WATCHED_ID = path.resolve('test/_tmp/input/watched'); - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - plugins: { - transform() { - this.addWatchFile('test/_tmp/input'); - return `export default ${existsSync(WATCHED_ID)}`; - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), true); - unlinkSync(WATCHED_ID); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), false); - watcher.close(); + const WATCHED_ID = resolve('test/_tmp/input/watched'); + return copy('test/watch/samples/watch-files', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + transform() { + this.addWatchFile('test/_tmp/input'); + return `export default ${existsSync(WATCHED_ID)}`; } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), true); + unlinkSync(WATCHED_ID); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), false); + watcher.close(); + } + ]); + }); }); it('respects initially missing added watched files', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - plugins: { - transform() { - this.addWatchFile('test/_tmp/input/dep'); - return `export default ${existsSync('test/_tmp/input/dep')}`; - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), false); - writeFileSync('test/_tmp/input/dep', ''); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), true); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + transform() { + this.addWatchFile('test/_tmp/input/dep'); + return `export default ${existsSync('test/_tmp/input/dep')}`; } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), false); + writeFileSync('test/_tmp/input/dep', ''); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), true); + } + ]); + }); }); it('respects unlinked and re-added watched files', () => { - return sander - .copydir('test/watch/samples/basic') - .to('test/_tmp/input') - .then(() => { - writeFileSync('test/_tmp/input/dep', ''); - watcher = rollup.watch({ - input: 'test/_tmp/input/main.js', - output: { - file: 'test/_tmp/output/bundle.js', - format: 'cjs', - exports: 'auto' - }, - plugins: { - transform() { - this.addWatchFile('test/_tmp/input/dep'); - return `export default ${existsSync('test/_tmp/input/dep')}`; - } - } - }); - - return sequence(watcher, [ - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), true); - unlinkSync('test/_tmp/input/dep'); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), false); - writeFileSync('test/_tmp/input/dep', ''); - }, - 'START', - 'BUNDLE_START', - 'BUNDLE_END', - 'END', - () => { - assert.strictEqual(run('../_tmp/output/bundle.js'), true); + return copy('test/watch/samples/basic', 'test/_tmp/input').then(() => { + writeFileSync('test/_tmp/input/dep', ''); + watcher = rollup.watch({ + input: 'test/_tmp/input/main.js', + output: { + file: 'test/_tmp/output/bundle.js', + format: 'cjs', + exports: 'auto' + }, + plugins: { + transform() { + this.addWatchFile('test/_tmp/input/dep'); + return `export default ${existsSync('test/_tmp/input/dep')}`; } - ]); + } }); + + return sequence(watcher, [ + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), true); + unlinkSync('test/_tmp/input/dep'); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), false); + writeFileSync('test/_tmp/input/dep', ''); + }, + 'START', + 'BUNDLE_START', + 'BUNDLE_END', + 'END', + () => { + assert.strictEqual(run('../_tmp/output/bundle.js'), true); + } + ]); + }); }); it('does not rerun the transform hook if a non-watched change triggered the re-run', () => { - const WATCHED_ID = path.resolve('test/_tmp/input/watched'); + const WATCHED_ID = resolve('test/_tmp/input/watched'); let transformRuns = 0; - return sander - .copydir('test/watch/samples/watch-files') - .to('test/_tmp/input') + return copy('test/watch/samples/watch-files', 'test/_tmp/input') .then(() => wait(100)) .then(() => { writeFileSync('test/_tmp/input/alsoWatched', 'initial');