diff --git a/src/fn/csv-to-docs.js b/src/fn/csv-to-docs.js index 7462fc9ff..6d9f1f3ac 100644 --- a/src/fn/csv-to-docs.js +++ b/src/fn/csv-to-docs.js @@ -29,6 +29,10 @@ const execute = () => { const jsonDir = `${environment.pathToProject}/json_docs`; fs.mkdir(jsonDir); + const warningMsg = `There are already docs in ${jsonDir}. + New json files will be created along side these existing docs.`; + fs.warnIfDirectoryIsNotEmpty(jsonDir, warningMsg); + const saveJsonDoc = doc => fs.write(`${jsonDir}/${doc._id}.doc.json`, safeStringify(doc) + '\n'); const model = { @@ -262,5 +266,5 @@ module.exports = { int, setCol, parseColumn, - removeExcludedField + removeExcludedField, }; diff --git a/src/lib/sync-fs.js b/src/lib/sync-fs.js index 188ffab9f..17fb0d362 100644 --- a/src/lib/sync-fs.js +++ b/src/lib/sync-fs.js @@ -4,6 +4,7 @@ const mkdirp = require('mkdirp').sync; const os = require('os'); const path = require('path'); const trace = require('../lib/log').trace; +const userPrompt = require('../lib/user-prompt'); const warn = require('../lib/log').warn; function read(path) { @@ -80,12 +81,27 @@ function copy(from, to, { overwrite=true }={}) { } } +function isDirectoryEmpty(dir) { + return !fs.readdirSync(dir).length; +} + +function warnIfDirectoryIsNotEmpty(dir, warningMsg) { + if (!isDirectoryEmpty(dir)) { + warn(warningMsg); + + if (!userPrompt.keyInYN('Are you sure you want to continue?')) { + throw new Error('User aborted execution.'); + } + } +} + module.exports = { copy, dirs, exists: fs.existsSync, extension, fs, + isDirectoryEmpty, mkdir: path => { try { mkdirp(path); } catch(e) { warn(e); } }, mkdtemp: () => fs.mkdtempSync(`${os.tmpdir()}/cht-conf`), path, @@ -98,6 +114,7 @@ module.exports = { deleteFilesInFolder: folderPath => recurseFiles(folderPath).forEach(filePath => fs.unlinkSync(filePath)), readdir: fs.readdirSync, statSync: fs.statSync, + warnIfDirectoryIsNotEmpty, withoutExtension, write: (path, data, options = 'utf8') => fs.writeFileSync(path, data, options), writeBinary: (path, content) => fs.writeFileSync(path, content), diff --git a/test/fn/csv-to-docs.spec.js b/test/fn/csv-to-docs.spec.js index 0f9f10f9d..cee9d052f 100644 --- a/test/fn/csv-to-docs.spec.js +++ b/test/fn/csv-to-docs.spec.js @@ -1,4 +1,4 @@ -const { assert } = require('chai'); +const { expect } = require('chai'); const sinon = require('sinon'); const csvToDocs = require('../../src/fn/csv-to-docs'); @@ -17,6 +17,7 @@ describe('csv-to-docs', function() { afterEach(function () { clock.restore(); + sinon.restore(); }); const testDir = `data/csv-to-docs`; @@ -28,6 +29,9 @@ describe('csv-to-docs', function() { // given dir = `${testDir}/${dir}`; sinon.stub(environment, 'pathToProject').get(() => dir); + const warnIfDirectoryIsNotEmptySpy = sinon.spy(fs, 'warnIfDirectoryIsNotEmpty'); + const warningMsg = `There are already docs in ${dir}. + New json files will be created along side these existing docs.`; // when csvToDocs.execute() @@ -36,7 +40,7 @@ describe('csv-to-docs', function() { const expectedDocsDir = `${dir}/expected-json_docs`; // then - assert.equal(countFilesInDir(generatedDocsDir), + expect(countFilesInDir(generatedDocsDir)).to.equal( countFilesInDir(expectedDocsDir ), `Different number of files in ${generatedDocsDir} and ${expectedDocsDir}.`); @@ -47,12 +51,14 @@ describe('csv-to-docs', function() { const generated = fs.read(`${generatedDocsDir}/${file}`); // and - assert.equal(generated, expected, `Different contents for "${file}"`); + expect(generated).to.equal(expected, `Different contents for "${file}"`); }); }) .then(done) .catch(done); + expect(warnIfDirectoryIsNotEmptySpy.calledOnceWith(dir, warningMsg)); + expect(warnIfDirectoryIsNotEmptySpy.threw('User aborted execution.')).to.be.false; }); }); diff --git a/test/lib/sync-fs.spec.js b/test/lib/sync-fs.spec.js index 7f6de163d..ff3f28744 100644 --- a/test/lib/sync-fs.spec.js +++ b/test/lib/sync-fs.spec.js @@ -1,6 +1,8 @@ -const assert = require('chai').assert; - +const { expect } = require('chai'); const fs = require('../../src/lib/sync-fs'); +const sinon = require('sinon'); +const userPrompt = require('../../src/lib/user-prompt'); +const { warn } = require('../../src/lib/log'); describe('sync-fs', () => { @@ -12,8 +14,78 @@ describe('sync-fs', () => { ].forEach(([input, expected]) => { it(`should convert ${input} to ${expected}`, () => { - assert.equal(fs.withoutExtension(input), expected); + expect(fs.withoutExtension(input), expected); }); }); }); + + describe('#isDirectoryEmpty()', () => { + afterEach(() => { + sinon.restore(); + }); + + it('should return true for an empty directory', () => { + const readdirSyncStub = sinon.stub(fs.fs, 'readdirSync').returns([]); + + const emptyDir = 'path/to/empty/directory'; + expect(fs.isDirectoryEmpty(emptyDir)).to.be.true; + + expect(readdirSyncStub.calledWith(emptyDir)).to.be.true; + }); + + it('should return false for a non-empty directory', () => { + const readdirSyncStub = sinon.stub(fs.fs, 'readdirSync').returns(['file1', 'file2']); + + const nonEmptyDir = 'path/to/non-empty/directory'; + expect(fs.isDirectoryEmpty(nonEmptyDir)).to.be.false; + + expect(readdirSyncStub.calledWith(nonEmptyDir)).to.be.true; + }); + }); + + describe('#warnIfDirectoryIsNotEmpty()', () => { + afterEach(() => { + sinon.restore(); + }); + + const warnSpy = sinon.spy(warn); + + it('should not trigger warning if directory is empty', () => { + const dir = 'emptyDirectory'; + const warningMsg = 'This is a warning message'; + + sinon.stub(fs.fs, 'readdirSync').returns([]); + sinon.stub(userPrompt, 'keyInYN').returns(true); + + fs.warnIfDirectoryIsNotEmpty(dir, warningMsg); + + expect(userPrompt.keyInYN.called).to.be.false; + }); + + it('should trigger warning and user prompt if directory is not empty', () => { + const dir = 'nonEmptyDirectory'; + const warningMsg = 'This is a warning message'; + + sinon.stub(fs.fs, 'readdirSync').returns(['file1']); + sinon.stub(userPrompt, 'keyInYN').returns(true); + + expect(() => fs.warnIfDirectoryIsNotEmpty(dir, warningMsg)).to.not.throw(); + + expect(warnSpy.calledWith(warningMsg)); + expect(userPrompt.keyInYN.calledWith('Are you sure you want to continue?')).to.be.true; + }); + + it('should throw an error if user chooses not to continue', () => { + const dir = 'nonEmptyDirectory'; + const warningMsg = 'This is a warning message'; + + sinon.stub(fs.fs, 'readdirSync').returns(['file1']); + sinon.stub(userPrompt, 'keyInYN').returns(false); + + expect(() => fs.warnIfDirectoryIsNotEmpty(dir, warningMsg)).to.throw('User aborted execution.'); + + expect(warnSpy.calledWith(warningMsg)); + expect(userPrompt.keyInYN.calledWith('Are you sure you want to continue?')).to.be.true; + }); + }); });