diff --git a/README.md b/README.md index 6371b489..245de668 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,8 @@ fs-extra contains hundreds of tests. - `npm run unit-esm`: runs tests for `fs-extra/esm` exports - `npm test`: runs the linter and all tests +When running unit tests, set the environment variable `CROSS_DEVICE_PATH` to the absolute path of an empty directory on another device (like a thumb drive) to enable cross-device move tests. + ### Windows diff --git a/lib/move/__tests__/cross-device-utils.js b/lib/move/__tests__/cross-device-utils.js new file mode 100644 index 00000000..b17b68e2 --- /dev/null +++ b/lib/move/__tests__/cross-device-utils.js @@ -0,0 +1,20 @@ +const fs = require('graceful-fs') +const path = require('path') + +const { CROSS_DEVICE_PATH } = process.env +let runCrossDeviceTests = !!CROSS_DEVICE_PATH + +if (runCrossDeviceTests) { + // make sure we have permission on device + try { + fs.writeFileSync(path.join(CROSS_DEVICE_PATH, 'file'), 'hi') + } catch { + runCrossDeviceTests = false + throw new Error(`Can't write to device ${CROSS_DEVICE_PATH}`) + } +} else console.log('Skipping cross-device move tests') + +module.exports = { + differentDevice: CROSS_DEVICE_PATH, + ifCrossDeviceEnabled: (fn) => runCrossDeviceTests ? fn : fn.skip +} diff --git a/lib/move/__tests__/move-preserve-timestamp.test.js b/lib/move/__tests__/move-preserve-timestamp.test.js index 3de89fba..e65c3a57 100644 --- a/lib/move/__tests__/move-preserve-timestamp.test.js +++ b/lib/move/__tests__/move-preserve-timestamp.test.js @@ -6,6 +6,7 @@ const path = require('path') const utimesSync = require('../../util/utimes').utimesMillisSync const assert = require('assert') const fse = require('../../index') +const { differentDevice, ifCrossDeviceEnabled } = require('./cross-device-utils') /* global beforeEach, afterEach, describe, it */ @@ -15,26 +16,10 @@ const describeIfPractical = process.arch === 'ia32' ? describe.skip : describe describeIfPractical('move() - across different devices', () => { let TEST_DIR, SRC, DEST, FILES - let __skipTests = false - const differentDevicePath = '/mnt' - - // must set this up, if not, exit silently - if (!fs.existsSync(differentDevicePath)) { - console.log('Skipping cross-device move test') - __skipTests = true - } - - // make sure we have permission on device - try { - fs.writeFileSync(path.join(differentDevicePath, 'file'), 'hi') - } catch { - console.log("Can't write to device. Skipping move test.") - __skipTests = true - } function setupFixture (readonly) { TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'move-sync-preserve-timestamp') - SRC = path.join(differentDevicePath, 'some/weird/dir-really-weird') + SRC = path.join(differentDevice, 'some/weird/dir-really-weird') DEST = path.join(TEST_DIR, 'dest') FILES = ['a-file', path.join('a-folder', 'another-file'), path.join('a-folder', 'another-folder', 'file3')] const timestamp = Date.now() / 1000 - 5 @@ -50,14 +35,12 @@ describeIfPractical('move() - across different devices', () => { }) } - const _it = __skipTests ? it.skip : it - afterEach(() => { fse.removeSync(TEST_DIR) fse.removeSync(SRC) }) - describe('> default behaviour', () => { + ifCrossDeviceEnabled(describe)('> default behaviour', () => { ;[ { subcase: 'writable', readonly: false }, { subcase: 'readonly', readonly: true } @@ -65,7 +48,7 @@ describeIfPractical('move() - across different devices', () => { describe(`>> with ${params.subcase} source files`, () => { beforeEach(() => setupFixture(params.readonly)) - _it('should have the same timestamps after move', done => { + it('should have the same timestamps after move', done => { const originalTimestamps = FILES.map(file => { const originalPath = path.join(SRC, file) const originalStat = fs.statSync(originalPath) diff --git a/lib/move/__tests__/move-sync-preserve-timestamp.test.js b/lib/move/__tests__/move-sync-preserve-timestamp.test.js index 3fa49483..816993b4 100644 --- a/lib/move/__tests__/move-sync-preserve-timestamp.test.js +++ b/lib/move/__tests__/move-sync-preserve-timestamp.test.js @@ -6,6 +6,7 @@ const path = require('path') const utimesSync = require('../../util/utimes').utimesMillisSync const assert = require('assert') const fse = require('../../index') +const { differentDevice, ifCrossDeviceEnabled } = require('./cross-device-utils') /* global beforeEach, afterEach, describe, it */ @@ -15,26 +16,10 @@ const describeIfPractical = process.arch === 'ia32' ? describe.skip : describe describeIfPractical('moveSync() - across different devices', () => { let TEST_DIR, SRC, DEST, FILES - let __skipTests = false - const differentDevicePath = '/mnt' - - // must set this up, if not, exit silently - if (!fs.existsSync(differentDevicePath)) { - console.log('Skipping cross-device move test') - __skipTests = true - } - - // make sure we have permission on device - try { - fs.writeFileSync(path.join(differentDevicePath, 'file'), 'hi') - } catch { - console.log("Can't write to device. Skipping move test.") - __skipTests = true - } function setupFixture (readonly) { TEST_DIR = path.join(os.tmpdir(), 'fs-extra', 'move-sync-preserve-timestamp') - SRC = path.join(differentDevicePath, 'some/weird/dir-really-weird') + SRC = path.join(differentDevice, 'some/weird/dir-really-weird') DEST = path.join(TEST_DIR, 'dest') FILES = ['a-file', path.join('a-folder', 'another-file'), path.join('a-folder', 'another-folder', 'file3')] const timestamp = Date.now() / 1000 - 5 @@ -50,14 +35,12 @@ describeIfPractical('moveSync() - across different devices', () => { }) } - const _it = __skipTests ? it.skip : it - afterEach(() => { fse.removeSync(TEST_DIR) fse.removeSync(SRC) }) - describe('> default behaviour', () => { + ifCrossDeviceEnabled(describe)('> default behaviour', () => { ;[ { subcase: 'writable', readonly: false }, { subcase: 'readonly', readonly: true } @@ -65,7 +48,7 @@ describeIfPractical('moveSync() - across different devices', () => { describe(`>> with ${params.subcase} source files`, () => { beforeEach(() => setupFixture(params.readonly)) - _it('should have the same timestamps after move', () => { + it('should have the same timestamps after move', () => { const originalTimestamps = FILES.map(file => { const originalPath = path.join(SRC, file) const originalStat = fs.statSync(originalPath) diff --git a/lib/move/__tests__/move-sync.test.js b/lib/move/__tests__/move-sync.test.js index 5f5b6dc6..de4166ab 100644 --- a/lib/move/__tests__/move-sync.test.js +++ b/lib/move/__tests__/move-sync.test.js @@ -7,6 +7,7 @@ const os = require('os') const fse = require('../..') const path = require('path') const assert = require('assert') +const { differentDevice, ifCrossDeviceEnabled } = require('./cross-device-utils') /* global afterEach, beforeEach, describe, it */ @@ -287,29 +288,10 @@ describe('moveSync()', () => { }) }) - describe('> when actually trying to move a folder across devices', () => { - const differentDevice = '/mnt' - let __skipTests = false - - // must set this up, if not, exit silently - if (!fs.existsSync(differentDevice)) { - console.log('Skipping cross-device moveSync test') - __skipTests = true - } - - // make sure we have permission on device - try { - fs.writeFileSync(path.join(differentDevice, 'file'), 'hi') - } catch { - console.log("Can't write to device. Skipping moveSync test.") - __skipTests = true - } - - const _it = __skipTests ? it.skip : it - + ifCrossDeviceEnabled(describe)('> when actually trying to move a folder across devices', () => { describe('> just the folder', () => { - _it('should move the folder', () => { - const src = '/mnt/some/weird/dir-really-weird' + it('should move the folder', () => { + const src = path.join(differentDevice, 'some/weird/dir-really-weird') const dest = path.join(TEST_DIR, 'device-weird') if (!fs.existsSync(src)) fse.mkdirpSync(src) diff --git a/lib/move/__tests__/move.test.js b/lib/move/__tests__/move.test.js index e7841caf..c1cc2a9e 100644 --- a/lib/move/__tests__/move.test.js +++ b/lib/move/__tests__/move.test.js @@ -5,6 +5,7 @@ const os = require('os') const fse = require('../../') const path = require('path') const assert = require('assert') +const { differentDevice, ifCrossDeviceEnabled } = require('./cross-device-utils') /* global afterEach, beforeEach, describe, it */ @@ -373,29 +374,10 @@ describe('+ move()', () => { // tested on Linux ubuntu 3.13.0-32-generic #57-Ubuntu SMP i686 i686 GNU/Linux // this won't trigger a bug on Mac OS X Yosimite with a USB drive (/Volumes) // see issue #108 - describe('> when actually trying to move a folder across devices', () => { - const differentDevice = '/mnt' - let __skipTests = false - - // must set this up, if not, exit silently - if (!fs.existsSync(differentDevice)) { - console.log('Skipping cross-device move test') - __skipTests = true - } - - // make sure we have permission on device - try { - fs.writeFileSync(path.join(differentDevice, 'file'), 'hi') - } catch { - console.log("Can't write to device. Skipping move test.") - __skipTests = true - } - - const _it = __skipTests ? it.skip : it - + ifCrossDeviceEnabled(describe)('> when actually trying to move a folder across devices', () => { describe('>> just the folder', () => { - _it('should move the folder', done => { - const src = '/mnt/some/weird/dir-really-weird' + it('should move the folder', done => { + const src = path.join(differentDevice, 'some/weird/dir-really-weird') const dest = path.join(TEST_DIR, 'device-weird') if (!fs.existsSync(src)) {