fs-jetpack
Advanced tools
Comparing version
/* eslint no-console: 0 */ | ||
'use strict'; | ||
"use strict"; | ||
const utils = require('./utils'); | ||
const utils = require("./utils"); | ||
const testDir = utils.prepareJetpackTestDir(); | ||
const toCopyDir = testDir.dir('to-copy'); | ||
const toCopyDir = testDir.dir("to-copy"); | ||
let timer; | ||
@@ -13,27 +13,30 @@ let jetpackTime; | ||
const test = (testConfig) => { | ||
console.log(''); | ||
const test = testConfig => { | ||
console.log(""); | ||
return utils.prepareFiles(toCopyDir, testConfig) | ||
.then(utils.waitAWhile) | ||
.then(() => { | ||
timer = utils.startTimer('jetpack.copyAsync()'); | ||
return toCopyDir.copyAsync('.', testDir.path('copied-jetpack')); | ||
}) | ||
.then(() => { | ||
jetpackTime = timer(); | ||
return utils.waitAWhile(); | ||
}) | ||
.then(() => { | ||
timer = utils.startTimer('Native cp -R'); | ||
return utils.exec(`cp -R ${toCopyDir.path()} ${testDir.path('copied-native')}`); | ||
}) | ||
.then(() => { | ||
nativeTime = timer(); | ||
utils.showDifferenceInfo(jetpackTime, nativeTime); | ||
return utils.cleanAfterTest(); | ||
}) | ||
.catch((err) => { | ||
console.log(err); | ||
}); | ||
return utils | ||
.prepareFiles(toCopyDir, testConfig) | ||
.then(utils.waitAWhile) | ||
.then(() => { | ||
timer = utils.startTimer("jetpack.copyAsync()"); | ||
return toCopyDir.copyAsync(".", testDir.path("copied-jetpack")); | ||
}) | ||
.then(() => { | ||
jetpackTime = timer(); | ||
return utils.waitAWhile(); | ||
}) | ||
.then(() => { | ||
timer = utils.startTimer("Native cp -R"); | ||
return utils.exec( | ||
`cp -R ${toCopyDir.path()} ${testDir.path("copied-native")}` | ||
); | ||
}) | ||
.then(() => { | ||
nativeTime = timer(); | ||
utils.showDifferenceInfo(jetpackTime, nativeTime); | ||
return utils.cleanAfterTest(); | ||
}) | ||
.catch(err => { | ||
console.log(err); | ||
}); | ||
}; | ||
@@ -44,8 +47,8 @@ | ||
files: 10000, | ||
size: 1000, | ||
size: 1000 | ||
}, | ||
{ | ||
files: 50, | ||
size: 1000 * 1000 * 10, | ||
}, | ||
size: 1000 * 1000 * 10 | ||
} | ||
]; | ||
@@ -52,0 +55,0 @@ |
/* eslint no-console: 0 */ | ||
'use strict'; | ||
"use strict"; | ||
const utils = require('./utils'); | ||
const utils = require("./utils"); | ||
@@ -12,33 +12,34 @@ const testDir = utils.prepareJetpackTestDir(); | ||
const test = (testConfig) => { | ||
const dirJet = testDir.dir('to-be-removed-by-jetpack'); | ||
const dirNative = testDir.dir('to-be-removed-by-native'); | ||
const test = testConfig => { | ||
const dirJet = testDir.dir("to-be-removed-by-jetpack"); | ||
const dirNative = testDir.dir("to-be-removed-by-native"); | ||
console.log(''); | ||
console.log(""); | ||
return utils.prepareFiles(dirJet, testConfig) | ||
.then(() => { | ||
return utils.prepareFiles(dirNative, testConfig); | ||
}) | ||
.then(utils.waitAWhile) | ||
.then(() => { | ||
timer = utils.startTimer('jetpack.removeAsync()'); | ||
return dirJet.removeAsync(); | ||
}) | ||
.then(() => { | ||
jetpackTime = timer(); | ||
return utils.waitAWhile(); | ||
}) | ||
.then(() => { | ||
timer = utils.startTimer('Native rm -rf'); | ||
return utils.exec(`rm -rf ${dirNative.path()}`); | ||
}) | ||
.then(() => { | ||
nativeTime = timer(); | ||
utils.showDifferenceInfo(jetpackTime, nativeTime); | ||
return utils.cleanAfterTest(); | ||
}) | ||
.catch((err) => { | ||
console.log(err); | ||
}); | ||
return utils | ||
.prepareFiles(dirJet, testConfig) | ||
.then(() => { | ||
return utils.prepareFiles(dirNative, testConfig); | ||
}) | ||
.then(utils.waitAWhile) | ||
.then(() => { | ||
timer = utils.startTimer("jetpack.removeAsync()"); | ||
return dirJet.removeAsync(); | ||
}) | ||
.then(() => { | ||
jetpackTime = timer(); | ||
return utils.waitAWhile(); | ||
}) | ||
.then(() => { | ||
timer = utils.startTimer("Native rm -rf"); | ||
return utils.exec(`rm -rf ${dirNative.path()}`); | ||
}) | ||
.then(() => { | ||
nativeTime = timer(); | ||
utils.showDifferenceInfo(jetpackTime, nativeTime); | ||
return utils.cleanAfterTest(); | ||
}) | ||
.catch(err => { | ||
console.log(err); | ||
}); | ||
}; | ||
@@ -49,4 +50,4 @@ | ||
files: 10000, | ||
size: 1000, | ||
}, | ||
size: 1000 | ||
} | ||
]; | ||
@@ -53,0 +54,0 @@ |
/* eslint no-console:0 */ | ||
'use strict'; | ||
"use strict"; | ||
const os = require('os'); | ||
const childProcess = require('child_process'); | ||
const prettyBytes = require('pretty-bytes'); | ||
const promisify = require('../lib/utils/promisify'); | ||
const jetpack = require('..'); | ||
const os = require("os"); | ||
const childProcess = require("child_process"); | ||
const prettyBytes = require("pretty-bytes"); | ||
const promisify = require("../lib/utils/promisify"); | ||
const jetpack = require(".."); | ||
@@ -25,4 +25,3 @@ const testDirPath = () => { | ||
const makeOneFile = () => { | ||
jetpackDir.fileAsync(`${count}.txt`, { content }) | ||
.then(() => { | ||
jetpackDir.fileAsync(`${count}.txt`, { content }).then(() => { | ||
count += 1; | ||
@@ -37,3 +36,7 @@ if (count < creationConfig.files) { | ||
console.log(`Preparing ${creationConfig.files} test files (${prettyBytes(creationConfig.size)} each)...`); | ||
console.log( | ||
`Preparing ${creationConfig.files} test files (${prettyBytes( | ||
creationConfig.size | ||
)} each)...` | ||
); | ||
makeOneFile(); | ||
@@ -43,3 +46,3 @@ }); | ||
const startTimer = (startMessage) => { | ||
const startTimer = startMessage => { | ||
const start = Date.now(); | ||
@@ -58,4 +61,4 @@ process.stdout.write(`${startMessage} ... `); | ||
const waitAWhile = () => { | ||
return new Promise((resolve) => { | ||
console.log('Waiting 5s to allow hardware buffers be emptied...'); | ||
return new Promise(resolve => { | ||
console.log("Waiting 5s to allow hardware buffers be emptied..."); | ||
setTimeout(resolve, 5000); | ||
@@ -71,3 +74,3 @@ }); | ||
const cleanAfterTest = () => { | ||
console.log('Cleaning up after test...'); | ||
console.log("Cleaning up after test..."); | ||
return jetpack.removeAsync(testDirPath()); | ||
@@ -83,3 +86,3 @@ }; | ||
showDifferenceInfo, | ||
cleanAfterTest, | ||
cleanAfterTest | ||
}; |
@@ -0,1 +1,4 @@ | ||
# 1.3.0 (2018-02-09) | ||
- `overwrite` function passed to `copyAsync()` can return promise. | ||
# 1.2.0 (2017-08-10) | ||
@@ -2,0 +5,0 @@ - Added symlinks search option to `find()`. |
@@ -1,13 +0,13 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('./utils/fs'); | ||
const write = require('./write'); | ||
const validate = require('./utils/validate'); | ||
const fs = require("./utils/fs"); | ||
const write = require("./write"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, path, data, options) => { | ||
const methodSignature = `${methodName}(path, data, [options])`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.argument(methodSignature, 'data', data, ['string', 'buffer']); | ||
validate.options(methodSignature, 'options', options, { | ||
mode: ['string', 'number'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.argument(methodSignature, "data", data, ["string", "buffer"]); | ||
validate.options(methodSignature, "options", options, { | ||
mode: ["string", "number"] | ||
}); | ||
@@ -24,3 +24,3 @@ }; | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Parent directory doesn't exist, so just pass the task to `write`, | ||
@@ -41,13 +41,14 @@ // which will create the folder and file. | ||
return new Promise((resolve, reject) => { | ||
fs.appendFile(path, data, options) | ||
.then(resolve) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// Parent directory doesn't exist, so just pass the task to `write`, | ||
// which will create the folder and file. | ||
write.async(path, data, options).then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.appendFile(path, data, options) | ||
.then(resolve) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// Parent directory doesn't exist, so just pass the task to `write`, | ||
// which will create the folder and file. | ||
write.async(path, data, options).then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -54,0 +55,0 @@ }; |
267
lib/copy.js
@@ -1,21 +0,21 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const dir = require('./dir'); | ||
const exists = require('./exists'); | ||
const inspect = require('./inspect'); | ||
const write = require('./write'); | ||
const matcher = require('./utils/matcher'); | ||
const fileMode = require('./utils/mode'); | ||
const treeWalker = require('./utils/tree_walker'); | ||
const validate = require('./utils/validate'); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const dir = require("./dir"); | ||
const exists = require("./exists"); | ||
const inspect = require("./inspect"); | ||
const write = require("./write"); | ||
const matcher = require("./utils/matcher"); | ||
const fileMode = require("./utils/mode"); | ||
const treeWalker = require("./utils/tree_walker"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, from, to, options) => { | ||
const methodSignature = `${methodName}(from, to, [options])`; | ||
validate.argument(methodSignature, 'from', from, ['string']); | ||
validate.argument(methodSignature, 'to', to, ['string']); | ||
validate.options(methodSignature, 'options', options, { | ||
overwrite: ['boolean', 'function'], | ||
matching: ['string', 'array of string'], | ||
validate.argument(methodSignature, "from", from, ["string"]); | ||
validate.argument(methodSignature, "to", to, ["string"]); | ||
validate.options(methodSignature, "options", options, { | ||
overwrite: ["boolean", "function"], | ||
matching: ["string", "array of string"] | ||
}); | ||
@@ -42,11 +42,11 @@ }; | ||
const generateNoSourceError = (path) => { | ||
const generateNoSourceError = path => { | ||
const err = new Error(`Path to copy doesn't exist ${path}`); | ||
err.code = 'ENOENT'; | ||
err.code = "ENOENT"; | ||
return err; | ||
}; | ||
const generateDestinationExistsError = (path) => { | ||
const generateDestinationExistsError = path => { | ||
const err = new Error(`Destination path already exists ${path}`); | ||
err.code = 'EEXIST'; | ||
err.code = "EEXIST"; | ||
return err; | ||
@@ -57,9 +57,12 @@ }; | ||
mode: true, | ||
symlinks: 'report', | ||
symlinks: "report", | ||
times: true, | ||
absolutePath: true, | ||
absolutePath: true | ||
}; | ||
const shouldThrowDestinationExistsError = (context) => { | ||
return typeof context.opts.overwrite !== 'function' && context.opts.overwrite !== true; | ||
const shouldThrowDestinationExistsError = context => { | ||
return ( | ||
typeof context.opts.overwrite !== "function" && | ||
context.opts.overwrite !== true | ||
); | ||
}; | ||
@@ -81,4 +84,4 @@ | ||
const canOverwriteItSync = (context) => { | ||
if (typeof context.opts.overwrite === 'function') { | ||
const canOverwriteItSync = context => { | ||
if (typeof context.opts.overwrite === "function") { | ||
const destInspectData = inspect.sync(context.destPath, inspectOptions); | ||
@@ -93,7 +96,7 @@ return context.opts.overwrite(context.srcInspectData, destInspectData); | ||
try { | ||
fs.writeFileSync(destPath, data, { mode, flag: 'wx' }); | ||
fs.writeFileSync(destPath, data, { mode, flag: "wx" }); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
write.sync(destPath, data, { mode }); | ||
} else if (err.code === 'EEXIST') { | ||
} else if (err.code === "EEXIST") { | ||
if (canOverwriteItSync(context)) { | ||
@@ -117,3 +120,3 @@ fs.writeFileSync(destPath, data, { mode }); | ||
// Must erase it manually, otherwise system won't allow us to place symlink there. | ||
if (err.code === 'EEXIST') { | ||
if (err.code === "EEXIST") { | ||
fs.unlinkSync(to); | ||
@@ -131,7 +134,7 @@ // Retry... | ||
const mode = fileMode.normalizeFileMode(srcInspectData.mode); | ||
if (srcInspectData.type === 'dir') { | ||
if (srcInspectData.type === "dir") { | ||
dir.createSync(destPath, { mode }); | ||
} else if (srcInspectData.type === 'file') { | ||
} else if (srcInspectData.type === "file") { | ||
copyFileSync(srcPath, destPath, mode, context); | ||
} else if (srcInspectData.type === 'symlink') { | ||
} else if (srcInspectData.type === "symlink") { | ||
copySymlinkSync(srcPath, destPath); | ||
@@ -160,25 +163,29 @@ } | ||
const checksBeforeCopyingAsync = (from, to, opts) => { | ||
return exists.async(from) | ||
.then((srcPathExists) => { | ||
if (!srcPathExists) { | ||
throw generateNoSourceError(from); | ||
} else { | ||
return exists.async(to); | ||
} | ||
}) | ||
.then((destPathExists) => { | ||
if (destPathExists && !opts.overwrite) { | ||
throw generateDestinationExistsError(to); | ||
} | ||
}); | ||
return exists | ||
.async(from) | ||
.then(srcPathExists => { | ||
if (!srcPathExists) { | ||
throw generateNoSourceError(from); | ||
} else { | ||
return exists.async(to); | ||
} | ||
}) | ||
.then(destPathExists => { | ||
if (destPathExists && !opts.overwrite) { | ||
throw generateDestinationExistsError(to); | ||
} | ||
}); | ||
}; | ||
const canOverwriteItAsync = (context) => { | ||
const canOverwriteItAsync = context => { | ||
return new Promise((resolve, reject) => { | ||
if (typeof context.opts.overwrite === 'function') { | ||
inspect.async(context.destPath, inspectOptions) | ||
.then((destInspectData) => { | ||
resolve(context.opts.overwrite(context.srcInspectData, destInspectData)); | ||
}) | ||
.catch(reject); | ||
if (typeof context.opts.overwrite === "function") { | ||
inspect | ||
.async(context.destPath, inspectOptions) | ||
.then(destInspectData => { | ||
resolve( | ||
context.opts.overwrite(context.srcInspectData, destInspectData) | ||
); | ||
}) | ||
.catch(reject); | ||
} else { | ||
@@ -194,5 +201,5 @@ resolve(context.opts.overwrite === true); | ||
let flags = 'wx'; | ||
let flags = "wx"; | ||
if (runOpts.overwrite) { | ||
flags = 'w'; | ||
flags = "w"; | ||
} | ||
@@ -203,5 +210,5 @@ | ||
readStream.on('error', reject); | ||
readStream.on("error", reject); | ||
writeStream.on('error', (err) => { | ||
writeStream.on("error", err => { | ||
// Force read stream to close, since write stream errored | ||
@@ -211,23 +218,27 @@ // read stream serves us no purpose. | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Some parent directory doesn't exits. Create it and retry. | ||
dir.createAsync(pathUtil.dirname(destPath)) | ||
.then(() => { | ||
copyFileAsync(srcPath, destPath, mode, context) | ||
.then(resolve, reject); | ||
}) | ||
.catch(reject); | ||
} else if (err.code === 'EEXIST') { | ||
dir | ||
.createAsync(pathUtil.dirname(destPath)) | ||
.then(() => { | ||
copyFileAsync(srcPath, destPath, mode, context).then( | ||
resolve, | ||
reject | ||
); | ||
}) | ||
.catch(reject); | ||
} else if (err.code === "EEXIST") { | ||
canOverwriteItAsync(context) | ||
.then((canOverwite) => { | ||
if (canOverwite) { | ||
copyFileAsync(srcPath, destPath, mode, context, { overwrite: true }) | ||
.then(resolve, reject); | ||
} else if (shouldThrowDestinationExistsError(context)) { | ||
reject(generateDestinationExistsError(destPath)); | ||
} else { | ||
resolve(); | ||
} | ||
}) | ||
.catch(reject); | ||
.then(canOverwite => { | ||
if (canOverwite) { | ||
copyFileAsync(srcPath, destPath, mode, context, { | ||
overwrite: true | ||
}).then(resolve, reject); | ||
} else if (shouldThrowDestinationExistsError(context)) { | ||
reject(generateDestinationExistsError(destPath)); | ||
} else { | ||
resolve(); | ||
} | ||
}) | ||
.catch(reject); | ||
} else { | ||
@@ -238,3 +249,3 @@ reject(err); | ||
writeStream.on('finish', resolve); | ||
writeStream.on("finish", resolve); | ||
@@ -246,21 +257,22 @@ readStream.pipe(writeStream); | ||
const copySymlinkAsync = (from, to) => { | ||
return fs.readlink(from) | ||
.then((symlinkPointsAt) => { | ||
return fs.readlink(from).then(symlinkPointsAt => { | ||
return new Promise((resolve, reject) => { | ||
fs.symlink(symlinkPointsAt, to) | ||
.then(resolve) | ||
.catch((err) => { | ||
if (err.code === 'EEXIST') { | ||
// There is already file/symlink with this name on destination location. | ||
// Must erase it manually, otherwise system won't allow us to place symlink there. | ||
fs.unlink(to) | ||
.then(() => { | ||
// Retry... | ||
return fs.symlink(symlinkPointsAt, to); | ||
}) | ||
.then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.symlink(symlinkPointsAt, to) | ||
.then(resolve) | ||
.catch(err => { | ||
if (err.code === "EEXIST") { | ||
// There is already file/symlink with this name on destination location. | ||
// Must erase it manually, otherwise system won't allow us to place symlink there. | ||
fs | ||
.unlink(to) | ||
.then(() => { | ||
// Retry... | ||
return fs.symlink(symlinkPointsAt, to); | ||
}) | ||
.then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -273,7 +285,7 @@ }); | ||
const mode = fileMode.normalizeFileMode(srcInspectData.mode); | ||
if (srcInspectData.type === 'dir') { | ||
if (srcInspectData.type === "dir") { | ||
return dir.createAsync(destPath, { mode }); | ||
} else if (srcInspectData.type === 'file') { | ||
} else if (srcInspectData.type === "file") { | ||
return copyFileAsync(srcPath, destPath, mode, context); | ||
} else if (srcInspectData.type === 'symlink') { | ||
} else if (srcInspectData.type === "symlink") { | ||
return copySymlinkAsync(srcPath, destPath); | ||
@@ -291,34 +303,35 @@ } | ||
checksBeforeCopyingAsync(from, to, opts) | ||
.then(() => { | ||
let allFilesDelivered = false; | ||
let filesInProgress = 0; | ||
.then(() => { | ||
let allFilesDelivered = false; | ||
let filesInProgress = 0; | ||
const stream = treeWalker.stream(from, { inspectOptions }) | ||
.on('readable', () => { | ||
const item = stream.read(); | ||
if (item) { | ||
const rel = pathUtil.relative(from, item.path); | ||
const destPath = pathUtil.resolve(to, rel); | ||
if (opts.allowedToCopy(item.path, item.item, destPath)) { | ||
filesInProgress += 1; | ||
copyItemAsync(item.path, item.item, destPath, opts) | ||
.then(() => { | ||
filesInProgress -= 1; | ||
if (allFilesDelivered && filesInProgress === 0) { | ||
resolve(); | ||
const stream = treeWalker | ||
.stream(from, { inspectOptions }) | ||
.on("readable", () => { | ||
const item = stream.read(); | ||
if (item) { | ||
const rel = pathUtil.relative(from, item.path); | ||
const destPath = pathUtil.resolve(to, rel); | ||
if (opts.allowedToCopy(item.path, item.item, destPath)) { | ||
filesInProgress += 1; | ||
copyItemAsync(item.path, item.item, destPath, opts) | ||
.then(() => { | ||
filesInProgress -= 1; | ||
if (allFilesDelivered && filesInProgress === 0) { | ||
resolve(); | ||
} | ||
}) | ||
.catch(reject); | ||
} | ||
}) | ||
.catch(reject); | ||
} | ||
} | ||
} | ||
}) | ||
.on("error", reject) | ||
.on("end", () => { | ||
allFilesDelivered = true; | ||
if (allFilesDelivered && filesInProgress === 0) { | ||
resolve(); | ||
} | ||
}); | ||
}) | ||
.on('error', reject) | ||
.on('end', () => { | ||
allFilesDelivered = true; | ||
if (allFilesDelivered && filesInProgress === 0) { | ||
resolve(); | ||
} | ||
}); | ||
}) | ||
.catch(reject); | ||
.catch(reject); | ||
}); | ||
@@ -325,0 +338,0 @@ }; |
189
lib/dir.js
@@ -1,21 +0,21 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const modeUtil = require('./utils/mode'); | ||
const validate = require('./utils/validate'); | ||
const remove = require('./remove'); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const modeUtil = require("./utils/mode"); | ||
const validate = require("./utils/validate"); | ||
const remove = require("./remove"); | ||
const validateInput = (methodName, path, criteria) => { | ||
const methodSignature = `${methodName}(path, [criteria])`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.options(methodSignature, 'criteria', criteria, { | ||
empty: ['boolean'], | ||
mode: ['string', 'number'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.options(methodSignature, "criteria", criteria, { | ||
empty: ["boolean"], | ||
mode: ["string", "number"] | ||
}); | ||
}; | ||
const getCriteriaDefaults = (passedCriteria) => { | ||
const getCriteriaDefaults = passedCriteria => { | ||
const criteria = passedCriteria || {}; | ||
if (typeof criteria.empty !== 'boolean') { | ||
if (typeof criteria.empty !== "boolean") { | ||
criteria.empty = false; | ||
@@ -29,4 +29,8 @@ } | ||
const generatePathOccupiedByNotDirectoryError = (path) => { | ||
return new Error(`Path ${path} exists but is not a directory. Halting jetpack.dir() call for safety reasons.`); | ||
const generatePathOccupiedByNotDirectoryError = path => { | ||
return new Error( | ||
`Path ${ | ||
path | ||
} exists but is not a directory. Halting jetpack.dir() call for safety reasons.` | ||
); | ||
}; | ||
@@ -38,3 +42,3 @@ | ||
const checkWhatAlreadyOccupiesPathSync = (path) => { | ||
const checkWhatAlreadyOccupiesPathSync = path => { | ||
let stat; | ||
@@ -46,3 +50,3 @@ | ||
// Detection if path already exists | ||
if (err.code !== 'ENOENT') { | ||
if (err.code !== "ENOENT") { | ||
throw err; | ||
@@ -65,3 +69,3 @@ } | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Parent directory doesn't exist. Need to create it first. | ||
@@ -71,3 +75,3 @@ createBrandNewDirectorySync(pathUtil.dirname(path), options); | ||
fs.mkdirSync(path, options.mode); | ||
} else if (err.code === 'EEXIST') { | ||
} else if (err.code === "EEXIST") { | ||
// The path already exists. We're fine. | ||
@@ -92,3 +96,3 @@ } else { | ||
const list = fs.readdirSync(path); | ||
list.forEach((filename) => { | ||
list.forEach(filename => { | ||
remove.sync(pathUtil.resolve(path, filename)); | ||
@@ -117,21 +121,22 @@ }); | ||
const checkWhatAlreadyOccupiesPathAsync = (path) => { | ||
const checkWhatAlreadyOccupiesPathAsync = path => { | ||
return new Promise((resolve, reject) => { | ||
fs.stat(path) | ||
.then((stat) => { | ||
if (stat.isDirectory()) { | ||
resolve(stat); | ||
} else { | ||
reject(generatePathOccupiedByNotDirectoryError(path)); | ||
} | ||
}) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// Path doesn't exist | ||
resolve(undefined); | ||
} else { | ||
// This is other error that nonexistent path, so end here. | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.stat(path) | ||
.then(stat => { | ||
if (stat.isDirectory()) { | ||
resolve(stat); | ||
} else { | ||
reject(generatePathOccupiedByNotDirectoryError(path)); | ||
} | ||
}) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// Path doesn't exist | ||
resolve(undefined); | ||
} else { | ||
// This is other error that nonexistent path, so end here. | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -141,20 +146,21 @@ }; | ||
// Delete all files and directores inside given directory | ||
const emptyAsync = (path) => { | ||
const emptyAsync = path => { | ||
return new Promise((resolve, reject) => { | ||
fs.readdir(path) | ||
.then((list) => { | ||
const doOne = (index) => { | ||
if (index === list.length) { | ||
resolve(); | ||
} else { | ||
const subPath = pathUtil.resolve(path, list[index]); | ||
remove.async(subPath).then(() => { | ||
doOne(index + 1); | ||
}); | ||
} | ||
}; | ||
fs | ||
.readdir(path) | ||
.then(list => { | ||
const doOne = index => { | ||
if (index === list.length) { | ||
resolve(); | ||
} else { | ||
const subPath = pathUtil.resolve(path, list[index]); | ||
remove.async(subPath).then(() => { | ||
doOne(index + 1); | ||
}); | ||
} | ||
}; | ||
doOne(0); | ||
}) | ||
.catch(reject); | ||
doOne(0); | ||
}) | ||
.catch(reject); | ||
}); | ||
@@ -181,4 +187,4 @@ }; | ||
checkMode() | ||
.then(checkEmptiness) | ||
.then(resolve, reject); | ||
.then(checkEmptiness) | ||
.then(resolve, reject); | ||
}); | ||
@@ -191,29 +197,30 @@ }; | ||
return new Promise((resolve, reject) => { | ||
fs.mkdir(path, options.mode) | ||
.then(resolve) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// Parent directory doesn't exist. Need to create it first. | ||
createBrandNewDirectoryAsync(pathUtil.dirname(path), options) | ||
.then(() => { | ||
// Now retry creating this directory. | ||
return fs.mkdir(path, options.mode); | ||
}) | ||
.then(resolve) | ||
.catch((err2) => { | ||
if (err2.code === 'EEXIST') { | ||
// Hmm, something other have already created the directory? | ||
// No problem for us. | ||
resolve(); | ||
} else { | ||
reject(err2); | ||
} | ||
}); | ||
} else if (err.code === 'EEXIST') { | ||
// The path already exists. We're fine. | ||
resolve(); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.mkdir(path, options.mode) | ||
.then(resolve) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// Parent directory doesn't exist. Need to create it first. | ||
createBrandNewDirectoryAsync(pathUtil.dirname(path), options) | ||
.then(() => { | ||
// Now retry creating this directory. | ||
return fs.mkdir(path, options.mode); | ||
}) | ||
.then(resolve) | ||
.catch(err2 => { | ||
if (err2.code === "EEXIST") { | ||
// Hmm, something other have already created the directory? | ||
// No problem for us. | ||
resolve(); | ||
} else { | ||
reject(err2); | ||
} | ||
}); | ||
} else if (err.code === "EEXIST") { | ||
// The path already exists. We're fine. | ||
resolve(); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -227,9 +234,13 @@ }; | ||
checkWhatAlreadyOccupiesPathAsync(path) | ||
.then((stat) => { | ||
if (stat !== undefined) { | ||
return checkExistingDirectoryFulfillsCriteriaAsync(path, stat, criteria); | ||
} | ||
return createBrandNewDirectoryAsync(path, criteria); | ||
}) | ||
.then(resolve, reject); | ||
.then(stat => { | ||
if (stat !== undefined) { | ||
return checkExistingDirectoryFulfillsCriteriaAsync( | ||
path, | ||
stat, | ||
criteria | ||
); | ||
} | ||
return createBrandNewDirectoryAsync(path, criteria); | ||
}) | ||
.then(resolve, reject); | ||
}); | ||
@@ -236,0 +247,0 @@ }; |
@@ -1,9 +0,9 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, path) => { | ||
const methodSignature = `${methodName}(path)`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
}; | ||
@@ -15,13 +15,13 @@ | ||
const existsSync = (path) => { | ||
const existsSync = path => { | ||
try { | ||
const stat = fs.statSync(path); | ||
if (stat.isDirectory()) { | ||
return 'dir'; | ||
return "dir"; | ||
} else if (stat.isFile()) { | ||
return 'file'; | ||
return "file"; | ||
} | ||
return 'other'; | ||
return "other"; | ||
} catch (err) { | ||
if (err.code !== 'ENOENT') { | ||
if (err.code !== "ENOENT") { | ||
throw err; | ||
@@ -38,7 +38,7 @@ } | ||
const existsAsync = (path) => { | ||
const existsAsync = path => { | ||
return new Promise((resolve, reject) => { | ||
fs.stat(path, (err, stat) => { | ||
if (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
resolve(false); | ||
@@ -49,7 +49,7 @@ } else { | ||
} else if (stat.isDirectory()) { | ||
resolve('dir'); | ||
resolve("dir"); | ||
} else if (stat.isFile()) { | ||
resolve('file'); | ||
resolve("file"); | ||
} else { | ||
resolve('other'); | ||
resolve("other"); | ||
} | ||
@@ -56,0 +56,0 @@ }); |
115
lib/file.js
@@ -1,19 +0,19 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('./utils/fs'); | ||
const modeUtil = require('./utils/mode'); | ||
const validate = require('./utils/validate'); | ||
const write = require('./write'); | ||
const fs = require("./utils/fs"); | ||
const modeUtil = require("./utils/mode"); | ||
const validate = require("./utils/validate"); | ||
const write = require("./write"); | ||
const validateInput = (methodName, path, criteria) => { | ||
const methodSignature = `${methodName}(path, [criteria])`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.options(methodSignature, 'criteria', criteria, { | ||
content: ['string', 'buffer', 'object', 'array'], | ||
jsonIndent: ['number'], | ||
mode: ['string', 'number'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.options(methodSignature, "criteria", criteria, { | ||
content: ["string", "buffer", "object", "array"], | ||
jsonIndent: ["number"], | ||
mode: ["string", "number"] | ||
}); | ||
}; | ||
const getCriteriaDefaults = (passedCriteria) => { | ||
const getCriteriaDefaults = passedCriteria => { | ||
const criteria = passedCriteria || {}; | ||
@@ -26,4 +26,8 @@ if (criteria.mode !== undefined) { | ||
const generatePathOccupiedByNotFileError = (path) => { | ||
return new Error(`Path ${path} exists but is not a file. Halting jetpack.file() call for safety reasons.`); | ||
const generatePathOccupiedByNotFileError = path => { | ||
return new Error( | ||
`Path ${ | ||
path | ||
} exists but is not a file. Halting jetpack.file() call for safety reasons.` | ||
); | ||
}; | ||
@@ -35,3 +39,3 @@ | ||
const checkWhatAlreadyOccupiesPathSync = (path) => { | ||
const checkWhatAlreadyOccupiesPathSync = path => { | ||
let stat; | ||
@@ -43,3 +47,3 @@ | ||
// Detection if path exists | ||
if (err.code !== 'ENOENT') { | ||
if (err.code !== "ENOENT") { | ||
throw err; | ||
@@ -63,3 +67,3 @@ } | ||
mode, | ||
jsonIndent: criteria.jsonIndent, | ||
jsonIndent: criteria.jsonIndent | ||
}); | ||
@@ -84,3 +88,3 @@ return true; | ||
const createBrandNewFileSync = (path, criteria) => { | ||
let content = ''; | ||
let content = ""; | ||
if (criteria.content !== undefined) { | ||
@@ -91,3 +95,3 @@ content = criteria.content; | ||
mode: criteria.mode, | ||
jsonIndent: criteria.jsonIndent, | ||
jsonIndent: criteria.jsonIndent | ||
}); | ||
@@ -110,21 +114,22 @@ }; | ||
const checkWhatAlreadyOccupiesPathAsync = (path) => { | ||
const checkWhatAlreadyOccupiesPathAsync = path => { | ||
return new Promise((resolve, reject) => { | ||
fs.stat(path) | ||
.then((stat) => { | ||
if (stat.isFile()) { | ||
resolve(stat); | ||
} else { | ||
reject(generatePathOccupiedByNotFileError(path)); | ||
} | ||
}) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// Path doesn't exist. | ||
resolve(undefined); | ||
} else { | ||
// This is other error. Must end here. | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.stat(path) | ||
.then(stat => { | ||
if (stat.isFile()) { | ||
resolve(stat); | ||
} else { | ||
reject(generatePathOccupiedByNotFileError(path)); | ||
} | ||
}) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// Path doesn't exist. | ||
resolve(undefined); | ||
} else { | ||
// This is other error. Must end here. | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -139,10 +144,11 @@ }; | ||
if (criteria.content !== undefined) { | ||
write.async(path, criteria.content, { | ||
mode, | ||
jsonIndent: criteria.jsonIndent, | ||
}) | ||
.then(() => { | ||
resolve(true); | ||
}) | ||
.catch(reject); | ||
write | ||
.async(path, criteria.content, { | ||
mode, | ||
jsonIndent: criteria.jsonIndent | ||
}) | ||
.then(() => { | ||
resolve(true); | ||
}) | ||
.catch(reject); | ||
} else { | ||
@@ -161,4 +167,3 @@ resolve(false); | ||
return checkContent() | ||
.then((contentReplaced) => { | ||
return checkContent().then(contentReplaced => { | ||
if (!contentReplaced) { | ||
@@ -172,3 +177,3 @@ return checkMode(); | ||
const createBrandNewFileAsync = (path, criteria) => { | ||
let content = ''; | ||
let content = ""; | ||
if (criteria.content !== undefined) { | ||
@@ -180,3 +185,3 @@ content = criteria.content; | ||
mode: criteria.mode, | ||
jsonIndent: criteria.jsonIndent, | ||
jsonIndent: criteria.jsonIndent | ||
}); | ||
@@ -190,9 +195,9 @@ }; | ||
checkWhatAlreadyOccupiesPathAsync(path) | ||
.then((stat) => { | ||
if (stat !== undefined) { | ||
return checkExistingFileFulfillsCriteriaAsync(path, stat, criteria); | ||
} | ||
return createBrandNewFileAsync(path, criteria); | ||
}) | ||
.then(resolve, reject); | ||
.then(stat => { | ||
if (stat !== undefined) { | ||
return checkExistingFileFulfillsCriteriaAsync(path, stat, criteria); | ||
} | ||
return createBrandNewFileAsync(path, criteria); | ||
}) | ||
.then(resolve, reject); | ||
}); | ||
@@ -199,0 +204,0 @@ }; |
120
lib/find.js
@@ -1,22 +0,22 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const treeWalker = require('./utils/tree_walker'); | ||
const inspect = require('./inspect'); | ||
const matcher = require('./utils/matcher'); | ||
const validate = require('./utils/validate'); | ||
const pathUtil = require("path"); | ||
const treeWalker = require("./utils/tree_walker"); | ||
const inspect = require("./inspect"); | ||
const matcher = require("./utils/matcher"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, path, options) => { | ||
const methodSignature = `${methodName}([path], options)`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.options(methodSignature, 'options', options, { | ||
matching: ['string', 'array of string'], | ||
files: ['boolean'], | ||
directories: ['boolean'], | ||
recursive: ['boolean'], | ||
symlinks: ['boolean'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.options(methodSignature, "options", options, { | ||
matching: ["string", "array of string"], | ||
files: ["boolean"], | ||
directories: ["boolean"], | ||
recursive: ["boolean"], | ||
symlinks: ["boolean"] | ||
}); | ||
}; | ||
const normalizeOptions = (options) => { | ||
const normalizeOptions = options => { | ||
const opts = options || {}; | ||
@@ -40,3 +40,3 @@ // defaults: | ||
const processFoundObjects = (foundObjects, cwd) => { | ||
return foundObjects.map((inspectObj) => { | ||
return foundObjects.map(inspectObj => { | ||
return pathUtil.relative(cwd, inspectObj.absolutePath); | ||
@@ -46,11 +46,13 @@ }); | ||
const generatePathDoesntExistError = (path) => { | ||
const generatePathDoesntExistError = path => { | ||
const err = new Error(`Path you want to find stuff in doesn't exist ${path}`); | ||
err.code = 'ENOENT'; | ||
err.code = "ENOENT"; | ||
return err; | ||
}; | ||
const generatePathNotDirectoryError = (path) => { | ||
const err = new Error(`Path you want to find stuff in must be a directory ${path}`); | ||
err.code = 'ENOTDIR'; | ||
const generatePathNotDirectoryError = path => { | ||
const err = new Error( | ||
`Path you want to find stuff in must be a directory ${path}` | ||
); | ||
err.code = "ENOTDIR"; | ||
return err; | ||
@@ -72,16 +74,22 @@ }; | ||
treeWalker.sync(path, { | ||
maxLevelsDeep, | ||
inspectOptions: { | ||
absolutePath: true, | ||
treeWalker.sync( | ||
path, | ||
{ | ||
maxLevelsDeep, | ||
inspectOptions: { | ||
absolutePath: true | ||
} | ||
}, | ||
}, (itemPath, item) => { | ||
if (itemPath !== path && matchesAnyOfGlobs(itemPath)) { | ||
if ((item.type === 'file' && options.files === true) | ||
|| (item.type === 'dir' && options.directories === true) | ||
|| (item.type === 'symlink' && options.symlinks === true)) { | ||
foundInspectObjects.push(item); | ||
(itemPath, item) => { | ||
if (itemPath !== path && matchesAnyOfGlobs(itemPath)) { | ||
if ( | ||
(item.type === "file" && options.files === true) || | ||
(item.type === "dir" && options.directories === true) || | ||
(item.type === "symlink" && options.symlinks === true) | ||
) { | ||
foundInspectObjects.push(item); | ||
} | ||
} | ||
} | ||
}); | ||
); | ||
@@ -95,3 +103,3 @@ return processFoundObjects(foundInspectObjects, options.cwd); | ||
throw generatePathDoesntExistError(path); | ||
} else if (entryPointInspect.type !== 'dir') { | ||
} else if (entryPointInspect.type !== "dir") { | ||
throw generatePathNotDirectoryError(path); | ||
@@ -117,23 +125,26 @@ } | ||
const walker = treeWalker.stream(path, { | ||
maxLevelsDeep, | ||
inspectOptions: { | ||
absolutePath: true, | ||
}, | ||
}) | ||
.on('readable', () => { | ||
const data = walker.read(); | ||
if (data && data.path !== path && matchesAnyOfGlobs(data.path)) { | ||
const item = data.item; | ||
if ((item.type === 'file' && options.files === true) | ||
|| (item.type === 'dir' && options.directories === true) | ||
|| (item.type === 'symlink' && options.symlinks === true)) { | ||
foundInspectObjects.push(item); | ||
const walker = treeWalker | ||
.stream(path, { | ||
maxLevelsDeep, | ||
inspectOptions: { | ||
absolutePath: true | ||
} | ||
} | ||
}) | ||
.on('error', reject) | ||
.on('end', () => { | ||
resolve(processFoundObjects(foundInspectObjects, options.cwd)); | ||
}); | ||
}) | ||
.on("readable", () => { | ||
const data = walker.read(); | ||
if (data && data.path !== path && matchesAnyOfGlobs(data.path)) { | ||
const item = data.item; | ||
if ( | ||
(item.type === "file" && options.files === true) || | ||
(item.type === "dir" && options.directories === true) || | ||
(item.type === "symlink" && options.symlinks === true) | ||
) { | ||
foundInspectObjects.push(item); | ||
} | ||
} | ||
}) | ||
.on("error", reject) | ||
.on("end", () => { | ||
resolve(processFoundObjects(foundInspectObjects, options.cwd)); | ||
}); | ||
}); | ||
@@ -143,7 +154,6 @@ }; | ||
const findAsyncInit = (path, options) => { | ||
return inspect.async(path) | ||
.then((entryPointInspect) => { | ||
return inspect.async(path).then(entryPointInspect => { | ||
if (entryPointInspect === undefined) { | ||
throw generatePathDoesntExistError(path); | ||
} else if (entryPointInspect.type !== 'dir') { | ||
} else if (entryPointInspect.type !== "dir") { | ||
throw generatePathNotDirectoryError(path); | ||
@@ -150,0 +160,0 @@ } |
@@ -1,26 +0,42 @@ | ||
'use strict'; | ||
"use strict"; | ||
const crypto = require('crypto'); | ||
const pathUtil = require('path'); | ||
const inspect = require('./inspect'); | ||
const list = require('./list'); | ||
const validate = require('./utils/validate'); | ||
const crypto = require("crypto"); | ||
const pathUtil = require("path"); | ||
const inspect = require("./inspect"); | ||
const list = require("./list"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, path, options) => { | ||
const methodSignature = `${methodName}(path, [options])`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.options(methodSignature, 'options', options, { | ||
checksum: ['string'], | ||
relativePath: ['boolean'], | ||
symlinks: ['string'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.options(methodSignature, "options", options, { | ||
checksum: ["string"], | ||
relativePath: ["boolean"], | ||
symlinks: ["string"] | ||
}); | ||
if (options && options.checksum !== undefined | ||
&& inspect.supportedChecksumAlgorithms.indexOf(options.checksum) === -1) { | ||
throw new Error(`Argument "options.checksum" passed to ${methodSignature} must have one of values: ${inspect.supportedChecksumAlgorithms.join(', ')}`); | ||
if ( | ||
options && | ||
options.checksum !== undefined && | ||
inspect.supportedChecksumAlgorithms.indexOf(options.checksum) === -1 | ||
) { | ||
throw new Error( | ||
`Argument "options.checksum" passed to ${ | ||
methodSignature | ||
} must have one of values: ${inspect.supportedChecksumAlgorithms.join( | ||
", " | ||
)}` | ||
); | ||
} | ||
if (options && options.symlinks !== undefined | ||
&& inspect.symlinkOptions.indexOf(options.symlinks) === -1) { | ||
throw new Error(`Argument "options.symlinks" passed to ${methodSignature} must have one of values: ${inspect.symlinkOptions.join(', ')}`); | ||
if ( | ||
options && | ||
options.symlinks !== undefined && | ||
inspect.symlinkOptions.indexOf(options.symlinks) === -1 | ||
) { | ||
throw new Error( | ||
`Argument "options.symlinks" passed to ${ | ||
methodSignature | ||
} must have one of values: ${inspect.symlinkOptions.join(", ")}` | ||
); | ||
} | ||
@@ -31,3 +47,3 @@ }; | ||
if (!parent) { | ||
return '.'; | ||
return "."; | ||
} | ||
@@ -41,6 +57,6 @@ return `${parent.relativePath}/${pathUtil.basename(path)}`; | ||
const hash = crypto.createHash(algo); | ||
inspectList.forEach((inspectObj) => { | ||
inspectList.forEach(inspectObj => { | ||
hash.update(inspectObj.name + inspectObj[algo]); | ||
}); | ||
return hash.digest('hex'); | ||
return hash.digest("hex"); | ||
}; | ||
@@ -60,7 +76,11 @@ | ||
if (treeBranch.type === 'dir') { | ||
if (treeBranch.type === "dir") { | ||
treeBranch.size = 0; | ||
treeBranch.children = list.sync(path).map((filename) => { | ||
treeBranch.children = list.sync(path).map(filename => { | ||
const subBranchPath = pathUtil.join(path, filename); | ||
const treeSubBranch = inspectTreeNodeSync(subBranchPath, options, treeBranch); | ||
const treeSubBranch = inspectTreeNodeSync( | ||
subBranchPath, | ||
options, | ||
treeBranch | ||
); | ||
// Add together all childrens' size to get directory combined size. | ||
@@ -72,3 +92,6 @@ treeBranch.size += treeSubBranch.size || 0; | ||
if (options.checksum) { | ||
treeBranch[options.checksum] = checksumOfDir(treeBranch.children, options.checksum); | ||
treeBranch[options.checksum] = checksumOfDir( | ||
treeBranch.children, | ||
options.checksum | ||
); | ||
} | ||
@@ -92,10 +115,13 @@ } | ||
return new Promise((resolve, reject) => { | ||
const inspectAllChildren = (treeBranch) => { | ||
const inspectAllChildren = treeBranch => { | ||
return new Promise((resolve2, reject2) => { | ||
list.async(path).then((children) => { | ||
const doNext = (index) => { | ||
list.async(path).then(children => { | ||
const doNext = index => { | ||
if (index === children.length) { | ||
if (options.checksum) { | ||
// We are done, but still have to calculate checksum of whole directory. | ||
treeBranch[options.checksum] = checksumOfDir(treeBranch.children, options.checksum); | ||
treeBranch[options.checksum] = checksumOfDir( | ||
treeBranch.children, | ||
options.checksum | ||
); | ||
} | ||
@@ -106,8 +132,8 @@ resolve2(); | ||
inspectTreeNodeAsync(subPath, options, treeBranch) | ||
.then((treeSubBranch) => { | ||
children[index] = treeSubBranch; | ||
treeBranch.size += treeSubBranch.size || 0; | ||
doNext(index + 1); | ||
}) | ||
.catch(reject2); | ||
.then(treeSubBranch => { | ||
children[index] = treeSubBranch; | ||
treeBranch.size += treeSubBranch.size || 0; | ||
doNext(index + 1); | ||
}) | ||
.catch(reject2); | ||
} | ||
@@ -124,24 +150,28 @@ }; | ||
inspect.async(path, options) | ||
.then((treeBranch) => { | ||
if (!treeBranch) { | ||
// Given path doesn't exist. We are done. | ||
resolve(treeBranch); | ||
} else { | ||
if (options.relativePath) { | ||
treeBranch.relativePath = generateTreeNodeRelativePath(parent, path); | ||
} | ||
if (treeBranch.type !== 'dir') { | ||
inspect | ||
.async(path, options) | ||
.then(treeBranch => { | ||
if (!treeBranch) { | ||
// Given path doesn't exist. We are done. | ||
resolve(treeBranch); | ||
} else { | ||
inspectAllChildren(treeBranch) | ||
.then(() => { | ||
if (options.relativePath) { | ||
treeBranch.relativePath = generateTreeNodeRelativePath( | ||
parent, | ||
path | ||
); | ||
} | ||
if (treeBranch.type !== "dir") { | ||
resolve(treeBranch); | ||
}) | ||
.catch(reject); | ||
} else { | ||
inspectAllChildren(treeBranch) | ||
.then(() => { | ||
resolve(treeBranch); | ||
}) | ||
.catch(reject); | ||
} | ||
} | ||
} | ||
}) | ||
.catch(reject); | ||
}) | ||
.catch(reject); | ||
}); | ||
@@ -148,0 +178,0 @@ }; |
@@ -1,31 +0,45 @@ | ||
'use strict'; | ||
"use strict"; | ||
const crypto = require('crypto'); | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const crypto = require("crypto"); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const supportedChecksumAlgorithms = ['md5', 'sha1', 'sha256', 'sha512']; | ||
const supportedChecksumAlgorithms = ["md5", "sha1", "sha256", "sha512"]; | ||
const symlinkOptions = ['report', 'follow']; | ||
const symlinkOptions = ["report", "follow"]; | ||
const validateInput = (methodName, path, options) => { | ||
const methodSignature = `${methodName}(path, [options])`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.options(methodSignature, 'options', options, { | ||
checksum: ['string'], | ||
mode: ['boolean'], | ||
times: ['boolean'], | ||
absolutePath: ['boolean'], | ||
symlinks: ['string'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.options(methodSignature, "options", options, { | ||
checksum: ["string"], | ||
mode: ["boolean"], | ||
times: ["boolean"], | ||
absolutePath: ["boolean"], | ||
symlinks: ["string"] | ||
}); | ||
if (options && options.checksum !== undefined | ||
&& supportedChecksumAlgorithms.indexOf(options.checksum) === -1) { | ||
throw new Error(`Argument "options.checksum" passed to ${methodSignature} must have one of values: ${supportedChecksumAlgorithms.join(', ')}`); | ||
if ( | ||
options && | ||
options.checksum !== undefined && | ||
supportedChecksumAlgorithms.indexOf(options.checksum) === -1 | ||
) { | ||
throw new Error( | ||
`Argument "options.checksum" passed to ${ | ||
methodSignature | ||
} must have one of values: ${supportedChecksumAlgorithms.join(", ")}` | ||
); | ||
} | ||
if (options && options.symlinks !== undefined | ||
&& symlinkOptions.indexOf(options.symlinks) === -1) { | ||
throw new Error(`Argument "options.symlinks" passed to ${methodSignature} must have one of values: ${symlinkOptions.join(', ')}`); | ||
if ( | ||
options && | ||
options.symlinks !== undefined && | ||
symlinkOptions.indexOf(options.symlinks) === -1 | ||
) { | ||
throw new Error( | ||
`Argument "options.symlinks" passed to ${ | ||
methodSignature | ||
} must have one of values: ${symlinkOptions.join(", ")}` | ||
); | ||
} | ||
@@ -40,10 +54,10 @@ }; | ||
if (stat.isFile()) { | ||
obj.type = 'file'; | ||
obj.type = "file"; | ||
obj.size = stat.size; | ||
} else if (stat.isDirectory()) { | ||
obj.type = 'dir'; | ||
obj.type = "dir"; | ||
} else if (stat.isSymbolicLink()) { | ||
obj.type = 'symlink'; | ||
obj.type = "symlink"; | ||
} else { | ||
obj.type = 'other'; | ||
obj.type = "other"; | ||
} | ||
@@ -76,9 +90,9 @@ | ||
hash.update(data); | ||
return hash.digest('hex'); | ||
return hash.digest("hex"); | ||
}; | ||
const addExtraFieldsSync = (path, inspectObj, options) => { | ||
if (inspectObj.type === 'file' && options.checksum) { | ||
if (inspectObj.type === "file" && options.checksum) { | ||
inspectObj[options.checksum] = fileChecksum(path, options.checksum); | ||
} else if (inspectObj.type === 'symlink') { | ||
} else if (inspectObj.type === "symlink") { | ||
inspectObj.pointsAt = fs.readlinkSync(path); | ||
@@ -93,3 +107,3 @@ } | ||
if (opts.symlinks === 'follow') { | ||
if (opts.symlinks === "follow") { | ||
statOperation = fs.statSync; | ||
@@ -102,3 +116,3 @@ } | ||
// Detection if path exists | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Doesn't exist. Return undefined instead of throwing. | ||
@@ -124,9 +138,9 @@ return undefined; | ||
const s = fs.createReadStream(path); | ||
s.on('data', (data) => { | ||
s.on("data", data => { | ||
hash.update(data); | ||
}); | ||
s.on('end', () => { | ||
resolve(hash.digest('hex')); | ||
s.on("end", () => { | ||
resolve(hash.digest("hex")); | ||
}); | ||
s.on('error', reject); | ||
s.on("error", reject); | ||
}); | ||
@@ -136,11 +150,9 @@ }; | ||
const addExtraFieldsAsync = (path, inspectObj, options) => { | ||
if (inspectObj.type === 'file' && options.checksum) { | ||
return fileChecksumAsync(path, options.checksum) | ||
.then((checksum) => { | ||
if (inspectObj.type === "file" && options.checksum) { | ||
return fileChecksumAsync(path, options.checksum).then(checksum => { | ||
inspectObj[options.checksum] = checksum; | ||
return inspectObj; | ||
}); | ||
} else if (inspectObj.type === 'symlink') { | ||
return fs.readlink(path) | ||
.then((linkPath) => { | ||
} else if (inspectObj.type === "symlink") { | ||
return fs.readlink(path).then(linkPath => { | ||
inspectObj.pointsAt = linkPath; | ||
@@ -158,3 +170,3 @@ return inspectObj; | ||
if (opts.symlinks === 'follow') { | ||
if (opts.symlinks === "follow") { | ||
statOperation = fs.stat; | ||
@@ -164,16 +176,15 @@ } | ||
statOperation(path) | ||
.then((stat) => { | ||
const inspectObj = createInspectObj(path, opts, stat); | ||
addExtraFieldsAsync(path, inspectObj, opts) | ||
.then(resolve, reject); | ||
}) | ||
.catch((err) => { | ||
// Detection if path exists | ||
if (err.code === 'ENOENT') { | ||
// Doesn't exist. Return undefined instead of throwing. | ||
resolve(undefined); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
.then(stat => { | ||
const inspectObj = createInspectObj(path, opts, stat); | ||
addExtraFieldsAsync(path, inspectObj, opts).then(resolve, reject); | ||
}) | ||
.catch(err => { | ||
// Detection if path exists | ||
if (err.code === "ENOENT") { | ||
// Doesn't exist. Return undefined instead of throwing. | ||
resolve(undefined); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -180,0 +191,0 @@ }; |
/* eslint no-param-reassign:0 */ | ||
'use strict'; | ||
"use strict"; | ||
const util = require('util'); | ||
const pathUtil = require('path'); | ||
const append = require('./append'); | ||
const dir = require('./dir'); | ||
const file = require('./file'); | ||
const find = require('./find'); | ||
const inspect = require('./inspect'); | ||
const inspectTree = require('./inspect_tree'); | ||
const copy = require('./copy'); | ||
const exists = require('./exists'); | ||
const list = require('./list'); | ||
const move = require('./move'); | ||
const read = require('./read'); | ||
const remove = require('./remove'); | ||
const rename = require('./rename'); | ||
const symlink = require('./symlink'); | ||
const streams = require('./streams'); | ||
const write = require('./write'); | ||
const util = require("util"); | ||
const pathUtil = require("path"); | ||
const append = require("./append"); | ||
const dir = require("./dir"); | ||
const file = require("./file"); | ||
const find = require("./find"); | ||
const inspect = require("./inspect"); | ||
const inspectTree = require("./inspect_tree"); | ||
const copy = require("./copy"); | ||
const exists = require("./exists"); | ||
const list = require("./list"); | ||
const move = require("./move"); | ||
const read = require("./read"); | ||
const remove = require("./remove"); | ||
const rename = require("./rename"); | ||
const symlink = require("./symlink"); | ||
const streams = require("./streams"); | ||
const write = require("./write"); | ||
@@ -27,3 +27,3 @@ // The Jetpack Context object. | ||
// passed cwdPath, or default process.cwd() if cwdPath was not specified. | ||
const jetpackContext = (cwdPath) => { | ||
const jetpackContext = cwdPath => { | ||
const getCwdPath = () => { | ||
@@ -33,3 +33,3 @@ return cwdPath || process.cwd(); | ||
const cwd = function () { | ||
const cwd = function() { | ||
// return current CWD if no arguments specified... | ||
@@ -47,7 +47,7 @@ if (arguments.length === 0) { | ||
// resolves path to inner CWD path of this jetpack instance | ||
const resolvePath = (path) => { | ||
const resolvePath = path => { | ||
return pathUtil.resolve(getCwdPath(), path); | ||
}; | ||
const getPath = function () { | ||
const getPath = function() { | ||
// add CWD base path as first element of arguments array | ||
@@ -58,3 +58,3 @@ Array.prototype.unshift.call(arguments, getCwdPath()); | ||
const normalizeOptions = (options) => { | ||
const normalizeOptions = options => { | ||
const opts = options || {}; | ||
@@ -72,7 +72,7 @@ opts.cwd = getCwdPath(); | ||
append: (path, data, options) => { | ||
append.validateInput('append', path, data, options); | ||
append.validateInput("append", path, data, options); | ||
append.sync(resolvePath(path), data, options); | ||
}, | ||
appendAsync: (path, data, options) => { | ||
append.validateInput('appendAsync', path, data, options); | ||
append.validateInput("appendAsync", path, data, options); | ||
return append.async(resolvePath(path), data, options); | ||
@@ -82,7 +82,7 @@ }, | ||
copy: (from, to, options) => { | ||
copy.validateInput('copy', from, to, options); | ||
copy.validateInput("copy", from, to, options); | ||
copy.sync(resolvePath(from), resolvePath(to), options); | ||
}, | ||
copyAsync: (from, to, options) => { | ||
copy.validateInput('copyAsync', from, to, options); | ||
copy.validateInput("copyAsync", from, to, options); | ||
return copy.async(resolvePath(from), resolvePath(to), options); | ||
@@ -99,3 +99,3 @@ }, | ||
dir: (path, criteria) => { | ||
dir.validateInput('dir', path, criteria); | ||
dir.validateInput("dir", path, criteria); | ||
const normalizedPath = resolvePath(path); | ||
@@ -106,7 +106,6 @@ dir.sync(normalizedPath, criteria); | ||
dirAsync: (path, criteria) => { | ||
dir.validateInput('dirAsync', path, criteria); | ||
dir.validateInput("dirAsync", path, criteria); | ||
return new Promise((resolve, reject) => { | ||
const normalizedPath = resolvePath(path); | ||
dir.async(normalizedPath, criteria) | ||
.then(() => { | ||
dir.async(normalizedPath, criteria).then(() => { | ||
resolve(cwd(normalizedPath)); | ||
@@ -117,8 +116,8 @@ }, reject); | ||
exists: (path) => { | ||
exists.validateInput('exists', path); | ||
exists: path => { | ||
exists.validateInput("exists", path); | ||
return exists.sync(resolvePath(path)); | ||
}, | ||
existsAsync: (path) => { | ||
exists.validateInput('existsAsync', path); | ||
existsAsync: path => { | ||
exists.validateInput("existsAsync", path); | ||
return exists.async(resolvePath(path)); | ||
@@ -128,3 +127,3 @@ }, | ||
file: (path, criteria) => { | ||
file.validateInput('file', path, criteria); | ||
file.validateInput("file", path, criteria); | ||
file.sync(resolvePath(path), criteria); | ||
@@ -134,6 +133,5 @@ return api; | ||
fileAsync: (path, criteria) => { | ||
file.validateInput('fileAsync', path, criteria); | ||
file.validateInput("fileAsync", path, criteria); | ||
return new Promise((resolve, reject) => { | ||
file.async(resolvePath(path), criteria) | ||
.then(() => { | ||
file.async(resolvePath(path), criteria).then(() => { | ||
resolve(api); | ||
@@ -147,7 +145,7 @@ }, reject); | ||
// to proper places and default startPath to CWD. | ||
if (typeof options === 'undefined' && typeof startPath === 'object') { | ||
if (typeof options === "undefined" && typeof startPath === "object") { | ||
options = startPath; | ||
startPath = '.'; | ||
startPath = "."; | ||
} | ||
find.validateInput('find', startPath, options); | ||
find.validateInput("find", startPath, options); | ||
return find.sync(resolvePath(startPath), normalizeOptions(options)); | ||
@@ -158,7 +156,7 @@ }, | ||
// to proper places and default startPath to CWD. | ||
if (typeof options === 'undefined' && typeof startPath === 'object') { | ||
if (typeof options === "undefined" && typeof startPath === "object") { | ||
options = startPath; | ||
startPath = '.'; | ||
startPath = "."; | ||
} | ||
find.validateInput('findAsync', startPath, options); | ||
find.validateInput("findAsync", startPath, options); | ||
return find.async(resolvePath(startPath), normalizeOptions(options)); | ||
@@ -168,7 +166,7 @@ }, | ||
inspect: (path, fieldsToInclude) => { | ||
inspect.validateInput('inspect', path, fieldsToInclude); | ||
inspect.validateInput("inspect", path, fieldsToInclude); | ||
return inspect.sync(resolvePath(path), fieldsToInclude); | ||
}, | ||
inspectAsync: (path, fieldsToInclude) => { | ||
inspect.validateInput('inspectAsync', path, fieldsToInclude); | ||
inspect.validateInput("inspectAsync", path, fieldsToInclude); | ||
return inspect.async(resolvePath(path), fieldsToInclude); | ||
@@ -178,25 +176,25 @@ }, | ||
inspectTree: (path, options) => { | ||
inspectTree.validateInput('inspectTree', path, options); | ||
inspectTree.validateInput("inspectTree", path, options); | ||
return inspectTree.sync(resolvePath(path), options); | ||
}, | ||
inspectTreeAsync: (path, options) => { | ||
inspectTree.validateInput('inspectTreeAsync', path, options); | ||
inspectTree.validateInput("inspectTreeAsync", path, options); | ||
return inspectTree.async(resolvePath(path), options); | ||
}, | ||
list: (path) => { | ||
list.validateInput('list', path); | ||
return list.sync(resolvePath(path || '.')); | ||
list: path => { | ||
list.validateInput("list", path); | ||
return list.sync(resolvePath(path || ".")); | ||
}, | ||
listAsync: (path) => { | ||
list.validateInput('listAsync', path); | ||
return list.async(resolvePath(path || '.')); | ||
listAsync: path => { | ||
list.validateInput("listAsync", path); | ||
return list.async(resolvePath(path || ".")); | ||
}, | ||
move: (from, to) => { | ||
move.validateInput('move', from, to); | ||
move.validateInput("move", from, to); | ||
move.sync(resolvePath(from), resolvePath(to)); | ||
}, | ||
moveAsync: (from, to) => { | ||
move.validateInput('moveAsync', from, to); | ||
move.validateInput("moveAsync", from, to); | ||
return move.async(resolvePath(from), resolvePath(to)); | ||
@@ -206,27 +204,27 @@ }, | ||
read: (path, returnAs) => { | ||
read.validateInput('read', path, returnAs); | ||
read.validateInput("read", path, returnAs); | ||
return read.sync(resolvePath(path), returnAs); | ||
}, | ||
readAsync: (path, returnAs) => { | ||
read.validateInput('readAsync', path, returnAs); | ||
read.validateInput("readAsync", path, returnAs); | ||
return read.async(resolvePath(path), returnAs); | ||
}, | ||
remove: (path) => { | ||
remove.validateInput('remove', path); | ||
remove: path => { | ||
remove.validateInput("remove", path); | ||
// If path not specified defaults to CWD | ||
remove.sync(resolvePath(path || '.')); | ||
remove.sync(resolvePath(path || ".")); | ||
}, | ||
removeAsync: (path) => { | ||
remove.validateInput('removeAsync', path); | ||
removeAsync: path => { | ||
remove.validateInput("removeAsync", path); | ||
// If path not specified defaults to CWD | ||
return remove.async(resolvePath(path || '.')); | ||
return remove.async(resolvePath(path || ".")); | ||
}, | ||
rename: (path, newName) => { | ||
rename.validateInput('rename', path, newName); | ||
rename.validateInput("rename", path, newName); | ||
rename.sync(resolvePath(path), newName); | ||
}, | ||
renameAsync: (path, newName) => { | ||
rename.validateInput('renameAsync', path, newName); | ||
rename.validateInput("renameAsync", path, newName); | ||
return rename.async(resolvePath(path), newName); | ||
@@ -236,7 +234,7 @@ }, | ||
symlink: (symlinkValue, path) => { | ||
symlink.validateInput('symlink', symlinkValue, path); | ||
symlink.validateInput("symlink", symlinkValue, path); | ||
symlink.sync(symlinkValue, resolvePath(path)); | ||
}, | ||
symlinkAsync: (symlinkValue, path) => { | ||
symlink.validateInput('symlinkAsync', symlinkValue, path); | ||
symlink.validateInput("symlinkAsync", symlinkValue, path); | ||
return symlink.async(symlinkValue, resolvePath(path)); | ||
@@ -246,9 +244,9 @@ }, | ||
write: (path, data, options) => { | ||
write.validateInput('write', path, data, options); | ||
write.validateInput("write", path, data, options); | ||
write.sync(resolvePath(path), data, options); | ||
}, | ||
writeAsync: (path, data, options) => { | ||
write.validateInput('writeAsync', path, data, options); | ||
write.validateInput("writeAsync", path, data, options); | ||
return write.async(resolvePath(path), data, options); | ||
}, | ||
} | ||
}; | ||
@@ -255,0 +253,0 @@ |
@@ -1,9 +0,9 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, path) => { | ||
const methodSignature = `${methodName}(path)`; | ||
validate.argument(methodSignature, 'path', path, ['string', 'undefined']); | ||
validate.argument(methodSignature, "path", path, ["string", "undefined"]); | ||
}; | ||
@@ -15,7 +15,7 @@ | ||
const listSync = (path) => { | ||
const listSync = path => { | ||
try { | ||
return fs.readdirSync(path); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Doesn't exist. Return undefined instead of throwing. | ||
@@ -32,16 +32,17 @@ return undefined; | ||
const listAsync = (path) => { | ||
const listAsync = path => { | ||
return new Promise((resolve, reject) => { | ||
fs.readdir(path) | ||
.then((list) => { | ||
resolve(list); | ||
}) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// Doesn't exist. Return undefined instead of throwing. | ||
resolve(undefined); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.readdir(path) | ||
.then(list => { | ||
resolve(list); | ||
}) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// Doesn't exist. Return undefined instead of throwing. | ||
resolve(undefined); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -48,0 +49,0 @@ }; |
@@ -1,18 +0,18 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const dir = require('./dir'); | ||
const exists = require('./exists'); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const dir = require("./dir"); | ||
const exists = require("./exists"); | ||
const validateInput = (methodName, from, to) => { | ||
const methodSignature = `${methodName}(from, to)`; | ||
validate.argument(methodSignature, 'from', from, ['string']); | ||
validate.argument(methodSignature, 'to', to, ['string']); | ||
validate.argument(methodSignature, "from", from, ["string"]); | ||
validate.argument(methodSignature, "to", to, ["string"]); | ||
}; | ||
const generateSourceDoesntExistError = (path) => { | ||
const generateSourceDoesntExistError = path => { | ||
const err = new Error(`Path to move doesn't exist ${path}`); | ||
err.code = 'ENOENT'; | ||
err.code = "ENOENT"; | ||
return err; | ||
@@ -29,3 +29,3 @@ }; | ||
} catch (err) { | ||
if (err.code !== 'ENOENT') { | ||
if (err.code !== "ENOENT") { | ||
// We can't make sense of this error. Rethrow it. | ||
@@ -53,16 +53,16 @@ throw err; | ||
const ensureDestinationPathExistsAsync = (to) => { | ||
const ensureDestinationPathExistsAsync = to => { | ||
return new Promise((resolve, reject) => { | ||
const destDir = pathUtil.dirname(to); | ||
exists.async(destDir) | ||
.then((dstExists) => { | ||
if (!dstExists) { | ||
dir.createAsync(destDir) | ||
.then(resolve, reject); | ||
} else { | ||
// Hah, no idea. | ||
reject(); | ||
} | ||
}) | ||
.catch(reject); | ||
exists | ||
.async(destDir) | ||
.then(dstExists => { | ||
if (!dstExists) { | ||
dir.createAsync(destDir).then(resolve, reject); | ||
} else { | ||
// Hah, no idea. | ||
reject(); | ||
} | ||
}) | ||
.catch(reject); | ||
}); | ||
@@ -73,27 +73,29 @@ }; | ||
return new Promise((resolve, reject) => { | ||
fs.rename(from, to) | ||
.then(resolve) | ||
.catch((err) => { | ||
if (err.code !== 'ENOENT') { | ||
// Something unknown. Rethrow original error. | ||
reject(err); | ||
} else { | ||
// Ok, source or destination path doesn't exist. | ||
// Must do more investigation. | ||
exists.async(from) | ||
.then((srcExists) => { | ||
if (!srcExists) { | ||
reject(generateSourceDoesntExistError(from)); | ||
} else { | ||
ensureDestinationPathExistsAsync(to) | ||
.then(() => { | ||
// Retry the attempt | ||
return fs.rename(from, to); | ||
fs | ||
.rename(from, to) | ||
.then(resolve) | ||
.catch(err => { | ||
if (err.code !== "ENOENT") { | ||
// Something unknown. Rethrow original error. | ||
reject(err); | ||
} else { | ||
// Ok, source or destination path doesn't exist. | ||
// Must do more investigation. | ||
exists | ||
.async(from) | ||
.then(srcExists => { | ||
if (!srcExists) { | ||
reject(generateSourceDoesntExistError(from)); | ||
} else { | ||
ensureDestinationPathExistsAsync(to) | ||
.then(() => { | ||
// Retry the attempt | ||
return fs.rename(from, to); | ||
}) | ||
.then(resolve, reject); | ||
} | ||
}) | ||
.then(resolve, reject); | ||
} | ||
}) | ||
.catch(reject); | ||
} | ||
}); | ||
.catch(reject); | ||
} | ||
}); | ||
}); | ||
@@ -100,0 +102,0 @@ }; |
/* eslint no-console:1 */ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const supportedReturnAs = ['utf8', 'buffer', 'json', 'jsonWithDates']; | ||
const supportedReturnAs = ["utf8", "buffer", "json", "jsonWithDates"]; | ||
const validateInput = (methodName, path, returnAs) => { | ||
const methodSignature = `${methodName}(path, returnAs)`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.argument(methodSignature, 'returnAs', returnAs, ['string', 'undefined']); | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.argument(methodSignature, "returnAs", returnAs, [ | ||
"string", | ||
"undefined" | ||
]); | ||
if (returnAs && supportedReturnAs.indexOf(returnAs) === -1) { | ||
throw new Error(`Argument "returnAs" passed to ${methodSignature} must have one of values: ${supportedReturnAs.join(', ')}`); | ||
throw new Error( | ||
`Argument "returnAs" passed to ${ | ||
methodSignature | ||
} must have one of values: ${supportedReturnAs.join(", ")}` | ||
); | ||
} | ||
@@ -24,3 +31,3 @@ }; | ||
const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/; | ||
if (typeof value === 'string') { | ||
if (typeof value === "string") { | ||
if (reISO.exec(value)) { | ||
@@ -34,3 +41,5 @@ return new Date(value); | ||
const makeNicerJsonParsingError = (path, err) => { | ||
const nicerError = new Error(`JSON parsing failed while reading ${path} [${err}]`); | ||
const nicerError = new Error( | ||
`JSON parsing failed while reading ${path} [${err}]` | ||
); | ||
nicerError.originalError = err; | ||
@@ -45,7 +54,7 @@ return nicerError; | ||
const readSync = (path, returnAs) => { | ||
const retAs = returnAs || 'utf8'; | ||
const retAs = returnAs || "utf8"; | ||
let data; | ||
let encoding = 'utf8'; | ||
if (retAs === 'buffer') { | ||
let encoding = "utf8"; | ||
if (retAs === "buffer") { | ||
encoding = null; | ||
@@ -57,3 +66,3 @@ } | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// If file doesn't exist return undefined instead of throwing. | ||
@@ -67,5 +76,5 @@ return undefined; | ||
try { | ||
if (retAs === 'json') { | ||
if (retAs === "json") { | ||
data = JSON.parse(data); | ||
} else if (retAs === 'jsonWithDates') { | ||
} else if (retAs === "jsonWithDates") { | ||
data = JSON.parse(data, jsonDateParser); | ||
@@ -86,32 +95,33 @@ } | ||
return new Promise((resolve, reject) => { | ||
const retAs = returnAs || 'utf8'; | ||
let encoding = 'utf8'; | ||
if (retAs === 'buffer') { | ||
const retAs = returnAs || "utf8"; | ||
let encoding = "utf8"; | ||
if (retAs === "buffer") { | ||
encoding = null; | ||
} | ||
fs.readFile(path, { encoding }) | ||
.then((data) => { | ||
// Make final parsing of the data before returning. | ||
try { | ||
if (retAs === 'json') { | ||
resolve(JSON.parse(data)); | ||
} else if (retAs === 'jsonWithDates') { | ||
resolve(JSON.parse(data, jsonDateParser)); | ||
fs | ||
.readFile(path, { encoding }) | ||
.then(data => { | ||
// Make final parsing of the data before returning. | ||
try { | ||
if (retAs === "json") { | ||
resolve(JSON.parse(data)); | ||
} else if (retAs === "jsonWithDates") { | ||
resolve(JSON.parse(data, jsonDateParser)); | ||
} else { | ||
resolve(data); | ||
} | ||
} catch (err) { | ||
reject(makeNicerJsonParsingError(path, err)); | ||
} | ||
}) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// If file doesn't exist return undefined instead of throwing. | ||
resolve(undefined); | ||
} else { | ||
resolve(data); | ||
// Otherwise throw | ||
reject(err); | ||
} | ||
} catch (err) { | ||
reject(makeNicerJsonParsingError(path, err)); | ||
} | ||
}) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// If file doesn't exist return undefined instead of throwing. | ||
resolve(undefined); | ||
} else { | ||
// Otherwise throw | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
}); | ||
@@ -118,0 +128,0 @@ }; |
@@ -1,11 +0,11 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const list = require('./list'); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const list = require("./list"); | ||
const validateInput = (methodName, path) => { | ||
const methodSignature = `${methodName}([path])`; | ||
validate.argument(methodSignature, 'path', path, ['string', 'undefined']); | ||
validate.argument(methodSignature, "path", path, ["string", "undefined"]); | ||
}; | ||
@@ -17,3 +17,3 @@ | ||
const removeSync = (path) => { | ||
const removeSync = path => { | ||
try { | ||
@@ -23,5 +23,9 @@ // Assume the path is a file and just try to remove it. | ||
} catch (err) { | ||
if (err.code === 'EPERM' || err.code === 'EISDIR' || err.code === 'ENOTEMPTY') { | ||
if ( | ||
err.code === "EPERM" || | ||
err.code === "EISDIR" || | ||
err.code === "ENOTEMPTY" | ||
) { | ||
// Must delete everything inside the directory first. | ||
list.sync(path).forEach((filename) => { | ||
list.sync(path).forEach(filename => { | ||
removeSync(pathUtil.join(path, filename)); | ||
@@ -32,3 +36,3 @@ }); | ||
fs.rmdirSync(path); | ||
} else if (err.code === 'ENOENT') { | ||
} else if (err.code === "ENOENT") { | ||
// File already doesn't exist. We're done. | ||
@@ -48,3 +52,3 @@ } else { | ||
return new Promise((resolve, reject) => { | ||
const retryInAWhileOrFail = (err) => { | ||
const retryInAWhileOrFail = err => { | ||
if (retryCount === 3) { | ||
@@ -56,4 +60,3 @@ // Too many retries already. Fail. | ||
setTimeout(() => { | ||
removeAsyncInternal(path, retryCount + 1) | ||
.then(resolve, reject); | ||
removeAsyncInternal(path, retryCount + 1).then(resolve, reject); | ||
}, 100); | ||
@@ -64,5 +67,4 @@ } | ||
const removeEverythingInsideDirectory = () => { | ||
return list.async(path) | ||
.then((filenamesInsideDir) => { | ||
const promises = filenamesInsideDir.map((filename) => { | ||
return list.async(path).then(filenamesInsideDir => { | ||
const promises = filenamesInsideDir.map(filename => { | ||
return removeAsyncInternal(pathUtil.join(path, filename), 0); | ||
@@ -75,37 +77,46 @@ }); | ||
// Assume the path is a file and just try to remove it. | ||
fs.unlink(path) | ||
.then(resolve) | ||
.catch((err) => { | ||
if (err.code === 'EBUSY') { | ||
retryInAWhileOrFail(err); | ||
} else if (err.code === 'EPERM' || err.code === 'EISDIR' || err.code === 'ENOTEMPTY') { | ||
// File deletion attempt failed. Probably it's not a file, it's a directory. | ||
// So try to proceed with that assumption. | ||
removeEverythingInsideDirectory() | ||
.then(() => { | ||
// Now go for the directory. | ||
return fs.rmdir(path); | ||
}) | ||
.then(resolve) | ||
.catch((err2) => { | ||
if (err2.code === 'EBUSY' || err2.code === 'EPERM' || err2.code === 'ENOTEMPTY') { | ||
// Failed again. This might be due to other processes reading | ||
// something inside the directory. Let's take a nap and retry. | ||
retryInAWhileOrFail(err2); | ||
} else { | ||
reject(err2); | ||
} | ||
}); | ||
} else if (err.code === 'ENOENT') { | ||
// File already doesn't exist. We're done. | ||
resolve(); | ||
} else { | ||
// Something unexpected happened. Rethrow original error. | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.unlink(path) | ||
.then(resolve) | ||
.catch(err => { | ||
if (err.code === "EBUSY") { | ||
retryInAWhileOrFail(err); | ||
} else if ( | ||
err.code === "EPERM" || | ||
err.code === "EISDIR" || | ||
err.code === "ENOTEMPTY" | ||
) { | ||
// File deletion attempt failed. Probably it's not a file, it's a directory. | ||
// So try to proceed with that assumption. | ||
removeEverythingInsideDirectory() | ||
.then(() => { | ||
// Now go for the directory. | ||
return fs.rmdir(path); | ||
}) | ||
.then(resolve) | ||
.catch(err2 => { | ||
if ( | ||
err2.code === "EBUSY" || | ||
err2.code === "EPERM" || | ||
err2.code === "ENOTEMPTY" | ||
) { | ||
// Failed again. This might be due to other processes reading | ||
// something inside the directory. Let's take a nap and retry. | ||
retryInAWhileOrFail(err2); | ||
} else { | ||
reject(err2); | ||
} | ||
}); | ||
} else if (err.code === "ENOENT") { | ||
// File already doesn't exist. We're done. | ||
resolve(); | ||
} else { | ||
// Something unexpected happened. Rethrow original error. | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
}; | ||
const removeAsync = (path) => { | ||
const removeAsync = path => { | ||
return removeAsyncInternal(path, 0); | ||
@@ -112,0 +123,0 @@ }; |
@@ -1,11 +0,11 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const move = require('./move'); | ||
const validate = require('./utils/validate'); | ||
const pathUtil = require("path"); | ||
const move = require("./move"); | ||
const validate = require("./utils/validate"); | ||
const validateInput = (methodName, path, newName) => { | ||
const methodSignature = `${methodName}(path, newName)`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.argument(methodSignature, 'newName', newName, ['string']); | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.argument(methodSignature, "newName", newName, ["string"]); | ||
}; | ||
@@ -12,0 +12,0 @@ |
@@ -1,6 +0,6 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('fs'); | ||
const fs = require("fs"); | ||
exports.createWriteStream = fs.createWriteStream; | ||
exports.createReadStream = fs.createReadStream; |
@@ -1,12 +0,12 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const dir = require('./dir'); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const dir = require("./dir"); | ||
const validateInput = (methodName, symlinkValue, path) => { | ||
const methodSignature = `${methodName}(symlinkValue, path)`; | ||
validate.argument(methodSignature, 'symlinkValue', symlinkValue, ['string']); | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.argument(methodSignature, "symlinkValue", symlinkValue, ["string"]); | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
}; | ||
@@ -22,3 +22,3 @@ | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Parent directories don't exist. Just create them and rety. | ||
@@ -39,16 +39,18 @@ dir.createSync(pathUtil.dirname(path)); | ||
return new Promise((resolve, reject) => { | ||
fs.symlink(symlinkValue, path) | ||
.then(resolve) | ||
.catch((err) => { | ||
if (err.code === 'ENOENT') { | ||
// Parent directories don't exist. Just create them and rety. | ||
dir.createAsync(pathUtil.dirname(path)) | ||
.then(() => { | ||
return fs.symlink(symlinkValue, path); | ||
}) | ||
.then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.symlink(symlinkValue, path) | ||
.then(resolve) | ||
.catch(err => { | ||
if (err.code === "ENOENT") { | ||
// Parent directories don't exist. Just create them and rety. | ||
dir | ||
.createAsync(pathUtil.dirname(path)) | ||
.then(() => { | ||
return fs.symlink(symlinkValue, path); | ||
}) | ||
.then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -55,0 +57,0 @@ }; |
// Adater module exposing all `fs` methods with promises instead of callbacks. | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('fs'); | ||
const promisify = require('./promisify'); | ||
const fs = require("fs"); | ||
const promisify = require("./promisify"); | ||
const isCallbackMethod = (key) => { | ||
const isCallbackMethod = key => { | ||
return [ | ||
typeof fs[key] === 'function', | ||
typeof fs[key] === "function", | ||
!key.match(/Sync$/), | ||
!key.match(/^[A-Z]/), | ||
!key.match(/^create/), | ||
!key.match(/^(un)?watch/), | ||
!key.match(/^(un)?watch/) | ||
].every(Boolean); | ||
}; | ||
const adaptMethod = (name) => { | ||
const adaptMethod = name => { | ||
const original = fs[name]; | ||
@@ -26,5 +26,5 @@ return promisify(original); | ||
Object.keys(fs).forEach((key) => { | ||
Object.keys(fs).forEach(key => { | ||
if (isCallbackMethod(key)) { | ||
if (key === 'exists') { | ||
if (key === "exists") { | ||
// fs.exists() does not follow standard | ||
@@ -34,3 +34,3 @@ // Node callback conventions, and has | ||
adapted.exists = () => { | ||
throw new Error('fs.exists() is deprecated'); | ||
throw new Error("fs.exists() is deprecated"); | ||
}; | ||
@@ -37,0 +37,0 @@ } else { |
@@ -1,4 +0,4 @@ | ||
'use strict'; | ||
"use strict"; | ||
const Minimatch = require('minimatch').Minimatch; | ||
const Minimatch = require("minimatch").Minimatch; | ||
@@ -8,3 +8,3 @@ const convertPatternToAbsolutePath = (basePath, pattern) => { | ||
// any slash we need to turn it into absolute path. | ||
const hasSlash = (pattern.indexOf('/') !== -1); | ||
const hasSlash = pattern.indexOf("/") !== -1; | ||
const isAbsolute = /^!?\//.test(pattern); | ||
@@ -16,8 +16,10 @@ const isNegated = /^!/.test(pattern); | ||
// Throw out meaningful characters from the beginning ("!", "./"). | ||
const patternWithoutFirstCharacters = pattern.replace(/^!/, '').replace(/^\.\//, ''); | ||
const patternWithoutFirstCharacters = pattern | ||
.replace(/^!/, "") | ||
.replace(/^\.\//, ""); | ||
if (/\/$/.test(basePath)) { | ||
separator = ''; | ||
separator = ""; | ||
} else { | ||
separator = '/'; | ||
separator = "/"; | ||
} | ||
@@ -37,3 +39,3 @@ | ||
if (typeof patterns === 'string') { | ||
if (typeof patterns === "string") { | ||
normalizedPatterns = [patterns]; | ||
@@ -44,15 +46,16 @@ } else { | ||
const matchers = normalizedPatterns.map((pattern) => { | ||
return convertPatternToAbsolutePath(basePath, pattern); | ||
}) | ||
.map((pattern) => { | ||
return new Minimatch(pattern, { | ||
matchBase: true, | ||
nocomment: true, | ||
dot: true, | ||
const matchers = normalizedPatterns | ||
.map(pattern => { | ||
return convertPatternToAbsolutePath(basePath, pattern); | ||
}) | ||
.map(pattern => { | ||
return new Minimatch(pattern, { | ||
matchBase: true, | ||
nocomment: true, | ||
dot: true | ||
}); | ||
}); | ||
}); | ||
const performMatch = (absolutePath) => { | ||
let mode = 'matching'; | ||
const performMatch = absolutePath => { | ||
let mode = "matching"; | ||
let weHaveMatch = false; | ||
@@ -66,3 +69,3 @@ let currentMatcher; | ||
if (currentMatcher.negate) { | ||
mode = 'negation'; | ||
mode = "negation"; | ||
if (i === 0) { | ||
@@ -76,3 +79,7 @@ // There are only negated patterns in the set, | ||
if (mode === 'negation' && weHaveMatch && !currentMatcher.match(absolutePath)) { | ||
if ( | ||
mode === "negation" && | ||
weHaveMatch && | ||
!currentMatcher.match(absolutePath) | ||
) { | ||
// One negation match is enought to know we can reject this one. | ||
@@ -82,3 +89,3 @@ return false; | ||
if (mode === 'matching' && !weHaveMatch) { | ||
if (mode === "matching" && !weHaveMatch) { | ||
weHaveMatch = currentMatcher.match(absolutePath); | ||
@@ -85,0 +92,0 @@ } |
// Logic for unix file mode operations. | ||
'use strict'; | ||
"use strict"; | ||
// Converts mode to string 3 characters long. | ||
exports.normalizeFileMode = (mode) => { | ||
exports.normalizeFileMode = mode => { | ||
let modeAsString; | ||
if (typeof mode === 'number') { | ||
if (typeof mode === "number") { | ||
modeAsString = mode.toString(8); | ||
@@ -10,0 +10,0 @@ } else { |
@@ -1,5 +0,5 @@ | ||
'use strict'; | ||
"use strict"; | ||
module.exports = (fn) => { | ||
return function () { | ||
module.exports = fn => { | ||
return function() { | ||
const length = arguments.length; | ||
@@ -6,0 +6,0 @@ const args = new Array(length); |
/* eslint no-underscore-dangle:0 */ | ||
'use strict'; | ||
"use strict"; | ||
const Readable = require('stream').Readable; | ||
const pathUtil = require('path'); | ||
const inspect = require('../inspect'); | ||
const list = require('../list'); | ||
const Readable = require("stream").Readable; | ||
const pathUtil = require("path"); | ||
const inspect = require("../inspect"); | ||
const list = require("../list"); | ||
@@ -22,5 +22,10 @@ // --------------------------------------------------------- | ||
callback(path, item); | ||
if (item && item.type === 'dir' && currentLevel < options.maxLevelsDeep) { | ||
list.sync(path).forEach((child) => { | ||
walkSync(path + pathUtil.sep + child, options, callback, currentLevel + 1); | ||
if (item && item.type === "dir" && currentLevel < options.maxLevelsDeep) { | ||
list.sync(path).forEach(child => { | ||
walkSync( | ||
path + pathUtil.sep + child, | ||
options, | ||
callback, | ||
currentLevel + 1 | ||
); | ||
}); | ||
@@ -43,3 +48,3 @@ } | ||
parent: undefined, | ||
level: 0, | ||
level: 0 | ||
}; | ||
@@ -49,7 +54,7 @@ let running = false; | ||
const error = function (err) { | ||
rs.emit('error', err); | ||
const error = function(err) { | ||
rs.emit("error", err); | ||
}; | ||
const findNextUnprocessedNode = (node) => { | ||
const findNextUnprocessedNode = node => { | ||
if (node.nextSibling) { | ||
@@ -63,3 +68,3 @@ return node.nextSibling; | ||
const pushAndContinueMaybe = (data) => { | ||
const pushAndContinueMaybe = data => { | ||
const theyWantMore = rs.push(data); | ||
@@ -84,33 +89,39 @@ running = false; | ||
inspect.async(theNode.path, options.inspectOptions) | ||
.then((inspected) => { | ||
theNode.inspected = inspected; | ||
if (inspected && inspected.type === 'dir' && theNode.level < options.maxLevelsDeep) { | ||
list.async(theNode.path) | ||
.then((childrenNames) => { | ||
const children = childrenNames.map((name) => { | ||
return { | ||
name, | ||
path: theNode.path + pathUtil.sep + name, | ||
parent: theNode, | ||
level: theNode.level + 1, | ||
}; | ||
}); | ||
children.forEach((child, index) => { | ||
child.nextSibling = children[index + 1]; | ||
}); | ||
inspect | ||
.async(theNode.path, options.inspectOptions) | ||
.then(inspected => { | ||
theNode.inspected = inspected; | ||
if ( | ||
inspected && | ||
inspected.type === "dir" && | ||
theNode.level < options.maxLevelsDeep | ||
) { | ||
list | ||
.async(theNode.path) | ||
.then(childrenNames => { | ||
const children = childrenNames.map(name => { | ||
return { | ||
name, | ||
path: theNode.path + pathUtil.sep + name, | ||
parent: theNode, | ||
level: theNode.level + 1 | ||
}; | ||
}); | ||
children.forEach((child, index) => { | ||
child.nextSibling = children[index + 1]; | ||
}); | ||
nextTreeNode = children[0] || findNextUnprocessedNode(theNode); | ||
nextTreeNode = children[0] || findNextUnprocessedNode(theNode); | ||
pushAndContinueMaybe({ path: theNode.path, item: inspected }); | ||
}) | ||
.catch(error); | ||
} else { | ||
nextTreeNode = findNextUnprocessedNode(theNode); | ||
pushAndContinueMaybe({ path: theNode.path, item: inspected }); | ||
}) | ||
.catch(error); | ||
} else { | ||
nextTreeNode = findNextUnprocessedNode(theNode); | ||
pushAndContinueMaybe({ path: theNode.path, item: inspected }); | ||
} | ||
}) | ||
.catch(error); | ||
} | ||
}) | ||
.catch(error); | ||
}; | ||
rs._read = function () { | ||
rs._read = function() { | ||
if (!running) { | ||
@@ -117,0 +128,0 @@ readSome(); |
@@ -1,6 +0,6 @@ | ||
'use strict'; | ||
"use strict"; | ||
const prettyPrintTypes = (types) => { | ||
const addArticle = (str) => { | ||
const vowels = ['a', 'e', 'i', 'o', 'u']; | ||
const prettyPrintTypes = types => { | ||
const addArticle = str => { | ||
const vowels = ["a", "e", "i", "o", "u"]; | ||
if (vowels.indexOf(str[0]) !== -1) { | ||
@@ -12,15 +12,15 @@ return `an ${str}`; | ||
return types.map(addArticle).join(' or '); | ||
return types.map(addArticle).join(" or "); | ||
}; | ||
const isArrayOfNotation = (typeDefinition) => { | ||
const isArrayOfNotation = typeDefinition => { | ||
return /array of /.test(typeDefinition); | ||
}; | ||
const extractTypeFromArrayOfNotation = (typeDefinition) => { | ||
const extractTypeFromArrayOfNotation = typeDefinition => { | ||
// The notation is e.g. 'array of string' | ||
return typeDefinition.split(' of ')[1]; | ||
return typeDefinition.split(" of ")[1]; | ||
}; | ||
const isValidTypeDefinition = (typeStr) => { | ||
const isValidTypeDefinition = typeStr => { | ||
if (isArrayOfNotation(typeStr)) { | ||
@@ -31,12 +31,12 @@ return isValidTypeDefinition(extractTypeFromArrayOfNotation(typeStr)); | ||
return [ | ||
'string', | ||
'number', | ||
'boolean', | ||
'array', | ||
'object', | ||
'buffer', | ||
'null', | ||
'undefined', | ||
'function', | ||
].some((validType) => { | ||
"string", | ||
"number", | ||
"boolean", | ||
"array", | ||
"object", | ||
"buffer", | ||
"null", | ||
"undefined", | ||
"function" | ||
].some(validType => { | ||
return validType === typeStr; | ||
@@ -46,11 +46,11 @@ }); | ||
const detectType = (value) => { | ||
const detectType = value => { | ||
if (value === null) { | ||
return 'null'; | ||
return "null"; | ||
} | ||
if (Array.isArray(value)) { | ||
return 'array'; | ||
return "array"; | ||
} | ||
if (Buffer.isBuffer(value)) { | ||
return 'buffer'; | ||
return "buffer"; | ||
} | ||
@@ -65,13 +65,13 @@ | ||
const detectTypeDeep = (value) => { | ||
const detectTypeDeep = value => { | ||
let type = detectType(value); | ||
let typesInArray; | ||
if (type === 'array') { | ||
if (type === "array") { | ||
typesInArray = value | ||
.map((element) => { | ||
.map(element => { | ||
return detectType(element); | ||
}) | ||
.filter(onlyUniqueValuesInArrayFilter); | ||
type += ` of ${typesInArray.join(', ')}`; | ||
type += ` of ${typesInArray.join(", ")}`; | ||
} | ||
@@ -85,7 +85,7 @@ | ||
if (detectType(argumentValue) !== 'array') { | ||
if (detectType(argumentValue) !== "array") { | ||
return false; | ||
} | ||
return argumentValue.every((element) => { | ||
return argumentValue.every(element => { | ||
return detectType(element) === allowedTypeInArray; | ||
@@ -95,4 +95,9 @@ }); | ||
const validateArgument = (methodName, argumentName, argumentValue, argumentMustBe) => { | ||
const isOneOfAllowedTypes = argumentMustBe.some((type) => { | ||
const validateArgument = ( | ||
methodName, | ||
argumentName, | ||
argumentValue, | ||
argumentMustBe | ||
) => { | ||
const isOneOfAllowedTypes = argumentMustBe.some(type => { | ||
if (!isValidTypeDefinition(type)) { | ||
@@ -110,3 +115,9 @@ throw new Error(`Unknown type "${type}"`); | ||
if (!isOneOfAllowedTypes) { | ||
throw new Error(`Argument "${argumentName}" passed to ${methodName} must be ${prettyPrintTypes(argumentMustBe)}. Received ${detectTypeDeep(argumentValue)}`); | ||
throw new Error( | ||
`Argument "${argumentName}" passed to ${ | ||
methodName | ||
} must be ${prettyPrintTypes(argumentMustBe)}. Received ${detectTypeDeep( | ||
argumentValue | ||
)}` | ||
); | ||
} | ||
@@ -117,4 +128,4 @@ }; | ||
if (obj !== undefined) { | ||
validateArgument(methodName, optionsObjName, obj, ['object']); | ||
Object.keys(obj).forEach((key) => { | ||
validateArgument(methodName, optionsObjName, obj, ["object"]); | ||
Object.keys(obj).forEach(key => { | ||
const argName = `${optionsObjName}.${key}`; | ||
@@ -124,3 +135,5 @@ if (allowedOptions[key] !== undefined) { | ||
} else { | ||
throw new Error(`Unknown argument "${argName}" passed to ${methodName}`); | ||
throw new Error( | ||
`Unknown argument "${argName}" passed to ${methodName}` | ||
); | ||
} | ||
@@ -133,3 +146,3 @@ }); | ||
argument: validateArgument, | ||
options: validateOptions, | ||
options: validateOptions | ||
}; |
@@ -1,15 +0,20 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const fs = require('./utils/fs'); | ||
const validate = require('./utils/validate'); | ||
const dir = require('./dir'); | ||
const pathUtil = require("path"); | ||
const fs = require("./utils/fs"); | ||
const validate = require("./utils/validate"); | ||
const dir = require("./dir"); | ||
const validateInput = (methodName, path, data, options) => { | ||
const methodSignature = `${methodName}(path, data, [options])`; | ||
validate.argument(methodSignature, 'path', path, ['string']); | ||
validate.argument(methodSignature, 'data', data, ['string', 'buffer', 'object', 'array']); | ||
validate.options(methodSignature, 'options', options, { | ||
atomic: ['boolean'], | ||
jsonIndent: ['number'], | ||
validate.argument(methodSignature, "path", path, ["string"]); | ||
validate.argument(methodSignature, "data", data, [ | ||
"string", | ||
"buffer", | ||
"object", | ||
"array" | ||
]); | ||
validate.options(methodSignature, "options", options, { | ||
atomic: ["boolean"], | ||
jsonIndent: ["number"] | ||
}); | ||
@@ -19,13 +24,11 @@ }; | ||
// Temporary file extensions used for atomic file overwriting. | ||
const newExt = '.__new__'; | ||
const newExt = ".__new__"; | ||
const serializeToJsonMaybe = (data, jsonIndent) => { | ||
let indent = jsonIndent; | ||
if (typeof indent !== 'number') { | ||
if (typeof indent !== "number") { | ||
indent = 2; | ||
} | ||
if (typeof data === 'object' | ||
&& !Buffer.isBuffer(data) | ||
&& data !== null) { | ||
if (typeof data === "object" && !Buffer.isBuffer(data) && data !== null) { | ||
return JSON.stringify(data, null, indent); | ||
@@ -45,3 +48,3 @@ } | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
// Means parent directory doesn't exist, so create it and try again. | ||
@@ -82,19 +85,21 @@ dir.createSync(pathUtil.dirname(path)); | ||
return new Promise((resolve, reject) => { | ||
fs.writeFile(path, data, options) | ||
.then(resolve) | ||
.catch((err) => { | ||
// First attempt to write a file ended with error. | ||
// Check if this is not due to nonexistent parent directory. | ||
if (err.code === 'ENOENT') { | ||
// Parent directory doesn't exist, so create it and try again. | ||
dir.createAsync(pathUtil.dirname(path)) | ||
.then(() => { | ||
return fs.writeFile(path, data, options); | ||
}) | ||
.then(resolve, reject); | ||
} else { | ||
// Nope, some other error, throw it. | ||
reject(err); | ||
} | ||
}); | ||
fs | ||
.writeFile(path, data, options) | ||
.then(resolve) | ||
.catch(err => { | ||
// First attempt to write a file ended with error. | ||
// Check if this is not due to nonexistent parent directory. | ||
if (err.code === "ENOENT") { | ||
// Parent directory doesn't exist, so create it and try again. | ||
dir | ||
.createAsync(pathUtil.dirname(path)) | ||
.then(() => { | ||
return fs.writeFile(path, data, options); | ||
}) | ||
.then(resolve, reject); | ||
} else { | ||
// Nope, some other error, throw it. | ||
reject(err); | ||
} | ||
}); | ||
}); | ||
@@ -109,7 +114,7 @@ }; | ||
writeFileAsync(path + newExt, data, options) | ||
.then(() => { | ||
// ...next rename temp file to real path. | ||
return fs.rename(path + newExt, path); | ||
}) | ||
.then(resolve, reject); | ||
.then(() => { | ||
// ...next rename temp file to real path. | ||
return fs.rename(path + newExt, path); | ||
}) | ||
.then(resolve, reject); | ||
}); | ||
@@ -116,0 +121,0 @@ }; |
@@ -1,5 +0,5 @@ | ||
'use strict'; | ||
"use strict"; | ||
const jetpack = require('./lib/jetpack'); | ||
const jetpack = require("./lib/jetpack"); | ||
module.exports = jetpack(); |
{ | ||
"name": "fs-jetpack", | ||
"description": "Better file system API", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"author": "Jakub Szwacz <jakub@szwacz.com>", | ||
@@ -12,4 +12,2 @@ "dependencies": { | ||
"codecov": "^2.2.0", | ||
"eslint": "^3.19.0", | ||
"eslint-config-decent-code": "szwacz/eslint-config-decent-code", | ||
"fs-extra": "^0.16.3", | ||
@@ -20,2 +18,3 @@ "istanbul": "^0.4.5", | ||
"pre-commit": "^1.1.2", | ||
"prettier": "1.8.2", | ||
"pretty-bytes": "^4.0.2", | ||
@@ -30,4 +29,4 @@ "release-assist": "^1.0.1" | ||
"test-with-coverage": "istanbul cover _mocha -- 'spec/**/*.spec.js'", | ||
"lint": "eslint .", | ||
"lint-staged": "lint-staged", | ||
"prettier": "prettier --write \"./**/*.js\"", | ||
"release-start": "release-assist --start", | ||
@@ -48,3 +47,6 @@ "release-finish": "release-assist --finish" | ||
"lint-staged": { | ||
"*.js": "eslint" | ||
"*.js": [ | ||
"prettier --write", | ||
"git add" | ||
] | ||
}, | ||
@@ -51,0 +53,0 @@ "pre-commit": [ |
@@ -8,3 +8,29 @@ fs-jetpack [](https://travis-ci.org/szwacz/fs-jetpack) [](https://ci.appveyor.com/project/szwacz/fs-jetpack) [](https://codecov.io/gh/szwacz/fs-jetpack) | ||
## Installation | ||
# Table of Contents | ||
[Installation](#installation) | ||
[Sync & Async](#sync--async) | ||
**API:** | ||
[append](#appendpath-data-options) | ||
[copy](#copyfrom-to-options) | ||
[createReadStream](#createreadstreampath-options) | ||
[createWriteStream](#createwritestreampath-options) | ||
[cwd](#cwdpath) | ||
[dir](#dirpath-criteria) | ||
[exists](#existspath) | ||
[file](#filepath-criteria) | ||
[find](#findpath-searchoptions) | ||
[inspect](#inspectpath-options) | ||
[inspectTree](#inspecttreepath-options) | ||
[list](#listpath) | ||
[move](#movefrom-to) | ||
[path](#pathparts) | ||
[read](#readpath-returnas) | ||
[remove](#removepath) | ||
[rename](#renamepath-newname) | ||
[symlink](#symlinksymlinkvalue-path) | ||
[write](#writepath-data-options) | ||
# Installation | ||
``` | ||
@@ -43,23 +69,2 @@ npm install fs-jetpack | ||
- [append](#appendpath-data-options) | ||
- [copy](#copyfrom-to-options) | ||
- [createReadStream](#createreadstreampath-options) | ||
- [createWriteStream](#createwritestreampath-options) | ||
- [cwd](#cwdpath) | ||
- [dir](#dirpath-criteria) | ||
- [exists](#existspath) | ||
- [file](#filepath-criteria) | ||
- [find](#findpath-searchoptions) | ||
- [inspect](#inspectpath-options) | ||
- [inspectTree](#inspecttreepath-options) | ||
- [list](#listpath) | ||
- [move](#movefrom-to) | ||
- [path](#pathparts) | ||
- [read](#readpath-returnas) | ||
- [remove](#removepath) | ||
- [rename](#renamepath-newname) | ||
- [symlink](#symlinksymlinkvalue-path) | ||
- [write](#writepath-data-options) | ||
## append(path, data, [options]) | ||
@@ -89,3 +94,3 @@ asynchronous: **appendAsync(path, data, [options])** | ||
`options` (optional) additional options for customization. Is an `Object` with possible fields: | ||
* `overwrite` (default: `false`) Whether to overwrite destination path when it already exists. Can be `Boolean` or `Function`. For directories, source directory is merged with destination directory. If function was provided, every time there is a file conflict while copying the function will be invoked with [inspect](#inspectpath-options) objects of both: source and destination file and overwrites the file only if `true` has been returned from the function (see example below). | ||
* `overwrite` (default: `false`) Whether to overwrite destination path when it already exists. Can be `Boolean` or `Function`. For directories, source directory is merged with destination directory. If function was provided, every time there is a file conflict while copying the function will be invoked with [inspect](#inspectpath-options) objects of both: source and destination file and overwrites the file only if `true` has been returned from the function (see example below). In async mode, the overwrite function can also return a promise, so you can perform multi step processes to determine if file should be overwritten or not (see example below). | ||
* `matching` if defined will actually copy **only** items matching any of specified glob patterns and omit everything else ([all possible globs are described further in this readme](#matching-patterns)). | ||
@@ -109,2 +114,13 @@ | ||
// Asynchronously copies files from folder foo_1 to foo_final, | ||
// but overwrites only files containing "John Doe" string. | ||
jetpack.copyAsync('foo_1', 'foo_final', { | ||
overwrite: (srcInspectData, destInspectData) => { | ||
return jetpack.readAsync(srcInspectData.absolutePath,) | ||
.then((data) => { | ||
return data.includes('John Doe'); | ||
}); | ||
} | ||
}); | ||
// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'. | ||
@@ -111,0 +127,0 @@ jetpack.copy('foo', 'bar', { matching: '*.md' }); |
@@ -1,32 +0,31 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('append', () => { | ||
describe("append", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('appends String to file', () => { | ||
describe("appends String to file", () => { | ||
const preparations = () => { | ||
fse.writeFileSync('file.txt', 'abc'); | ||
fse.writeFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('abcxyz'); | ||
path("file.txt").shouldBeFileWithContent("abcxyz"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.append('file.txt', 'xyz'); | ||
jetpack.append("file.txt", "xyz"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.appendAsync('file.txt', 'xyz') | ||
.then(() => { | ||
jetpack.appendAsync("file.txt", "xyz").then(() => { | ||
expectations(); | ||
@@ -38,21 +37,20 @@ done(); | ||
describe('appends Buffer to file', () => { | ||
describe("appends Buffer to file", () => { | ||
const preparations = () => { | ||
fse.writeFileSync('file.bin', new Buffer([11])); | ||
fse.writeFileSync("file.bin", new Buffer([11])); | ||
}; | ||
const expectations = () => { | ||
path('file.bin').shouldBeFileWithContent(new Buffer([11, 22])); | ||
path("file.bin").shouldBeFileWithContent(new Buffer([11, 22])); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.append('file.bin', new Buffer([22])); | ||
jetpack.append("file.bin", new Buffer([22])); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.appendAsync('file.bin', new Buffer([22])) | ||
.then(() => { | ||
jetpack.appendAsync("file.bin", new Buffer([22])).then(() => { | ||
expectations(); | ||
@@ -66,13 +64,12 @@ done(); | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('xyz'); | ||
path("file.txt").shouldBeFileWithContent("xyz"); | ||
}; | ||
it('sync', () => { | ||
jetpack.append('file.txt', 'xyz'); | ||
it("sync", () => { | ||
jetpack.append("file.txt", "xyz"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.appendAsync('file.txt', 'xyz') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.appendAsync("file.txt", "xyz").then(() => { | ||
expectations(); | ||
@@ -86,13 +83,12 @@ done(); | ||
const expectations = () => { | ||
path('dir/dir/file.txt').shouldBeFileWithContent('xyz'); | ||
path("dir/dir/file.txt").shouldBeFileWithContent("xyz"); | ||
}; | ||
it('sync', () => { | ||
jetpack.append('dir/dir/file.txt', 'xyz'); | ||
it("sync", () => { | ||
jetpack.append("dir/dir/file.txt", "xyz"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.appendAsync('dir/dir/file.txt', 'xyz') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.appendAsync("dir/dir/file.txt", "xyz").then(() => { | ||
expectations(); | ||
@@ -104,23 +100,22 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b.txt').shouldBeFileWithContent('abcxyz'); | ||
path("a/b.txt").shouldBeFileWithContent("abcxyz"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.append('b.txt', 'xyz'); | ||
jetContext.append("b.txt", "xyz"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.appendAsync('b.txt', 'xyz') | ||
.then(() => { | ||
jetContext.appendAsync("b.txt", "xyz").then(() => { | ||
expectations(); | ||
@@ -132,14 +127,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.append, methodName: 'append' }, | ||
{ type: 'async', method: jetpack.appendAsync, methodName: 'appendAsync' }, | ||
{ type: "sync", method: jetpack.append, methodName: "append" }, | ||
{ type: "async", method: jetpack.appendAsync, methodName: "appendAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, 'xyz'); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, data, [options]) must be a string. Received undefined`); | ||
test.method(undefined, "xyz"); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -150,7 +149,11 @@ }); | ||
describe('"data" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc'); | ||
}).to.throw(`Argument "data" passed to ${test.methodName}(path, data, [options]) must be a string or a buffer. Received undefined`); | ||
test.method("abc"); | ||
}).to.throw( | ||
`Argument "data" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a string or a buffer. Received undefined` | ||
); | ||
}); | ||
@@ -162,7 +165,11 @@ }); | ||
describe('"mode" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', 'xyz', { mode: true }); | ||
}).to.throw(`Argument "options.mode" passed to ${test.methodName}(path, data, [options]) must be a string or a number. Received boolean`); | ||
test.method("abc", "xyz", { mode: true }); | ||
}).to.throw( | ||
`Argument "options.mode" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a string or a number. Received boolean` | ||
); | ||
}); | ||
@@ -174,16 +181,15 @@ }); | ||
if (process.platform !== 'win32') { | ||
describe('sets file mode on created file (unix only)', () => { | ||
if (process.platform !== "win32") { | ||
describe("sets file mode on created file (unix only)", () => { | ||
const expectations = () => { | ||
path('file.txt').shouldHaveMode('711'); | ||
path("file.txt").shouldHaveMode("711"); | ||
}; | ||
it('sync', () => { | ||
jetpack.append('file.txt', 'abc', { mode: '711' }); | ||
it("sync", () => { | ||
jetpack.append("file.txt", "abc", { mode: "711" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.appendAsync('file.txt', 'abc', { mode: '711' }) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.appendAsync("file.txt", "abc", { mode: "711" }).then(() => { | ||
expectations(); | ||
@@ -190,0 +196,0 @@ done(); |
@@ -1,4 +0,4 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fs = require('fs'); | ||
const fs = require("fs"); | ||
@@ -18,3 +18,3 @@ const areBuffersEqual = (bufA, bufB) => { | ||
module.exports = (path) => { | ||
module.exports = path => { | ||
return { | ||
@@ -27,3 +27,3 @@ shouldNotExist: () => { | ||
} catch (err) { | ||
if (err.code !== 'ENOENT') { | ||
if (err.code !== "ENOENT") { | ||
throw err; | ||
@@ -46,3 +46,3 @@ } | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
message = `Path ${path} should exist`; | ||
@@ -58,3 +58,3 @@ } else { | ||
shouldBeFileWithContent: (expectedContent) => { | ||
shouldBeFileWithContent: expectedContent => { | ||
let message; | ||
@@ -64,3 +64,5 @@ let content; | ||
const generateMessage = (expected, found) => { | ||
message = `File ${path} should have content "${expected}" but found "${found}"`; | ||
message = `File ${path} should have content "${expected}" but found "${ | ||
found | ||
}"`; | ||
}; | ||
@@ -72,6 +74,9 @@ | ||
if (!areBuffersEqual(expectedContent, content)) { | ||
generateMessage(expectedContent.toString('hex'), content.toString('hex')); | ||
generateMessage( | ||
expectedContent.toString("hex"), | ||
content.toString("hex") | ||
); | ||
} | ||
} else { | ||
content = fs.readFileSync(path, 'utf8'); | ||
content = fs.readFileSync(path, "utf8"); | ||
if (content !== expectedContent) { | ||
@@ -82,3 +87,3 @@ generateMessage(expectedContent, content); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
message = `File ${path} should exist`; | ||
@@ -94,3 +99,3 @@ } else { | ||
shouldHaveMode: (expectedMode) => { | ||
shouldHaveMode: expectedMode => { | ||
let mode; | ||
@@ -103,6 +108,8 @@ let message; | ||
if (mode !== expectedMode) { | ||
message = `Path ${path} should have mode "${expectedMode}" but have instead "${mode}"`; | ||
message = `Path ${path} should have mode "${ | ||
expectedMode | ||
}" but have instead "${mode}"`; | ||
} | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === "ENOENT") { | ||
message = `Path ${path} should exist`; | ||
@@ -116,4 +123,4 @@ } else { | ||
} | ||
}, | ||
} | ||
}; | ||
}; |
@@ -1,33 +0,32 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('copy', () => { | ||
describe("copy", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('copies a file', () => { | ||
describe("copies a file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', 'abc'); | ||
fse.outputFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('abc'); | ||
path('file_copied.txt').shouldBeFileWithContent('abc'); | ||
path("file.txt").shouldBeFileWithContent("abc"); | ||
path("file_copied.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('file.txt', 'file_copied.txt'); | ||
jetpack.copy("file.txt", "file_copied.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('file.txt', 'file_copied.txt') | ||
.then(() => { | ||
jetpack.copyAsync("file.txt", "file_copied.txt").then(() => { | ||
expectations(); | ||
@@ -39,22 +38,21 @@ done(); | ||
describe('can copy file to nonexistent directory (will create directory)', () => { | ||
describe("can copy file to nonexistent directory (will create directory)", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', 'abc'); | ||
fse.outputFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('abc'); | ||
path('dir/dir/file.txt').shouldBeFileWithContent('abc'); | ||
path("file.txt").shouldBeFileWithContent("abc"); | ||
path("dir/dir/file.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('file.txt', 'dir/dir/file.txt'); | ||
jetpack.copy("file.txt", "dir/dir/file.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('file.txt', 'dir/dir/file.txt') | ||
.then(() => { | ||
jetpack.copyAsync("file.txt", "dir/dir/file.txt").then(() => { | ||
expectations(); | ||
@@ -66,21 +64,20 @@ done(); | ||
describe('copies empty directory', () => { | ||
describe("copies empty directory", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('dir'); | ||
fse.mkdirsSync("dir"); | ||
}; | ||
const expectations = () => { | ||
path('copied/dir').shouldBeDirectory(); | ||
path("copied/dir").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('dir', 'copied/dir'); | ||
jetpack.copy("dir", "copied/dir"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('dir', 'copied/dir') | ||
.then(() => { | ||
jetpack.copyAsync("dir", "copied/dir").then(() => { | ||
expectations(); | ||
@@ -92,25 +89,24 @@ done(); | ||
describe('copies a tree of files', () => { | ||
describe("copies a tree of files", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/f1.txt', 'abc'); | ||
fse.outputFileSync('a/b/f2.txt', '123'); | ||
fse.mkdirsSync('a/b/c'); | ||
fse.outputFileSync("a/f1.txt", "abc"); | ||
fse.outputFileSync("a/b/f2.txt", "123"); | ||
fse.mkdirsSync("a/b/c"); | ||
}; | ||
const expectations = () => { | ||
path('copied/a/f1.txt').shouldBeFileWithContent('abc'); | ||
path('copied/a/b/c').shouldBeDirectory(); | ||
path('copied/a/b/f2.txt').shouldBeFileWithContent('123'); | ||
path("copied/a/f1.txt").shouldBeFileWithContent("abc"); | ||
path("copied/a/b/c").shouldBeDirectory(); | ||
path("copied/a/b/f2.txt").shouldBeFileWithContent("123"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('a', 'copied/a'); | ||
jetpack.copy("a", "copied/a"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('a', 'copied/a') | ||
.then(() => { | ||
jetpack.copyAsync("a", "copied/a").then(() => { | ||
expectations(); | ||
@@ -123,11 +119,11 @@ done(); | ||
describe("generates nice error if source path doesn't exist", () => { | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('ENOENT'); | ||
const expectations = err => { | ||
expect(err.code).to.equal("ENOENT"); | ||
expect(err.message).to.have.string("Path to copy doesn't exist"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
try { | ||
jetpack.copy('a', 'b'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.copy("a", "b"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -138,5 +134,4 @@ expectations(err); | ||
it('async', (done) => { | ||
jetpack.copyAsync('a', 'b') | ||
.catch((err) => { | ||
it("async", done => { | ||
jetpack.copyAsync("a", "b").catch(err => { | ||
expectations(err); | ||
@@ -148,24 +143,23 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b.txt').shouldBeFileWithContent('abc'); | ||
path('a/x.txt').shouldBeFileWithContent('abc'); | ||
path("a/b.txt").shouldBeFileWithContent("abc"); | ||
path("a/x.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.copy('b.txt', 'x.txt'); | ||
jetContext.copy("b.txt", "x.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.copyAsync('b.txt', 'x.txt') | ||
.then(() => { | ||
jetContext.copyAsync("b.txt", "x.txt").then(() => { | ||
expectations(); | ||
@@ -177,19 +171,19 @@ done(); | ||
describe('overwriting behaviour', () => { | ||
describe('does not overwrite by default', () => { | ||
describe("overwriting behaviour", () => { | ||
describe("does not overwrite by default", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/file.txt', 'abc'); | ||
fse.mkdirsSync('b'); | ||
fse.outputFileSync("a/file.txt", "abc"); | ||
fse.mkdirsSync("b"); | ||
}; | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('EEXIST'); | ||
expect(err.message).to.have.string('Destination path already exists'); | ||
const expectations = err => { | ||
expect(err.code).to.equal("EEXIST"); | ||
expect(err.message).to.have.string("Destination path already exists"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.copy('a', 'b'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.copy("a", "b"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -200,6 +194,5 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('a', 'b') | ||
.catch((err) => { | ||
jetpack.copyAsync("a", "b").catch(err => { | ||
expectations(err); | ||
@@ -211,23 +204,22 @@ done(); | ||
describe('overwrites if it was specified', () => { | ||
describe("overwrites if it was specified", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/file.txt', 'abc'); | ||
fse.outputFileSync('b/file.txt', 'xyz'); | ||
fse.outputFileSync("a/file.txt", "abc"); | ||
fse.outputFileSync("b/file.txt", "xyz"); | ||
}; | ||
const expectations = () => { | ||
path('a/file.txt').shouldBeFileWithContent('abc'); | ||
path('b/file.txt').shouldBeFileWithContent('abc'); | ||
path("a/file.txt").shouldBeFileWithContent("abc"); | ||
path("b/file.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('a', 'b', { overwrite: true }); | ||
jetpack.copy("a", "b", { overwrite: true }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('a', 'b', { overwrite: true }) | ||
.then(() => { | ||
jetpack.copyAsync("a", "b", { overwrite: true }).then(() => { | ||
expectations(); | ||
@@ -239,8 +231,8 @@ done(); | ||
describe('overwrites according to what function returns', () => { | ||
describe("overwrites according to what function returns", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('from-here/foo/canada.txt', 'abc'); | ||
fse.outputFileSync('to-here/foo/canada.txt', 'xyz'); | ||
fse.outputFileSync('from-here/foo/eh.txt', 'abc'); | ||
fse.outputFileSync('to-here/foo/eh.txt', 'xyz'); | ||
fse.outputFileSync("from-here/foo/canada.txt", "abc"); | ||
fse.outputFileSync("to-here/foo/canada.txt", "xyz"); | ||
fse.outputFileSync("from-here/foo/eh.txt", "abc"); | ||
fse.outputFileSync("to-here/foo/eh.txt", "xyz"); | ||
}; | ||
@@ -250,40 +242,39 @@ | ||
// canada is copied | ||
path('from-here/foo/canada.txt').shouldBeFileWithContent('abc'); | ||
path('to-here/foo/canada.txt').shouldBeFileWithContent('abc'); | ||
path("from-here/foo/canada.txt").shouldBeFileWithContent("abc"); | ||
path("to-here/foo/canada.txt").shouldBeFileWithContent("abc"); | ||
// eh is not copied | ||
path('from-here/foo/eh.txt').shouldBeFileWithContent('abc'); | ||
path('to-here/foo/eh.txt').shouldBeFileWithContent('xyz'); | ||
path("from-here/foo/eh.txt").shouldBeFileWithContent("abc"); | ||
path("to-here/foo/eh.txt").shouldBeFileWithContent("xyz"); | ||
}; | ||
const overwrite = (srcInspectData, destInspectData) => { | ||
expect(srcInspectData).to.have.property('name'); | ||
expect(srcInspectData).to.have.property('type'); | ||
expect(srcInspectData).to.have.property('mode'); | ||
expect(srcInspectData).to.have.property('accessTime'); | ||
expect(srcInspectData).to.have.property('modifyTime'); | ||
expect(srcInspectData).to.have.property('changeTime'); | ||
expect(srcInspectData).to.have.property('absolutePath'); | ||
expect(srcInspectData).to.have.property("name"); | ||
expect(srcInspectData).to.have.property("type"); | ||
expect(srcInspectData).to.have.property("mode"); | ||
expect(srcInspectData).to.have.property("accessTime"); | ||
expect(srcInspectData).to.have.property("modifyTime"); | ||
expect(srcInspectData).to.have.property("changeTime"); | ||
expect(srcInspectData).to.have.property("absolutePath"); | ||
expect(destInspectData).to.have.property('name'); | ||
expect(destInspectData).to.have.property('type'); | ||
expect(destInspectData).to.have.property('mode'); | ||
expect(destInspectData).to.have.property('accessTime'); | ||
expect(destInspectData).to.have.property('modifyTime'); | ||
expect(destInspectData).to.have.property('changeTime'); | ||
expect(destInspectData).to.have.property('absolutePath'); | ||
expect(destInspectData).to.have.property("name"); | ||
expect(destInspectData).to.have.property("type"); | ||
expect(destInspectData).to.have.property("mode"); | ||
expect(destInspectData).to.have.property("accessTime"); | ||
expect(destInspectData).to.have.property("modifyTime"); | ||
expect(destInspectData).to.have.property("changeTime"); | ||
expect(destInspectData).to.have.property("absolutePath"); | ||
return srcInspectData.name.includes('canada'); | ||
return srcInspectData.name.includes("canada"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('from-here', 'to-here', { overwrite }); | ||
jetpack.copy("from-here", "to-here", { overwrite }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('from-here', 'to-here', { overwrite }) | ||
.then(() => { | ||
jetpack.copyAsync("from-here", "to-here", { overwrite }).then(() => { | ||
expectations(); | ||
@@ -296,28 +287,68 @@ done(); | ||
describe('filter what to copy', () => { | ||
describe('by simple pattern', () => { | ||
describe("async overwrite function can return promise", () => { | ||
const preparations = () => { | ||
fse.outputFileSync("from-here/foo/canada.txt", "abc"); | ||
fse.outputFileSync("to-here/foo/canada.txt", "xyz"); | ||
fse.outputFileSync("from-here/foo/eh.txt", "123"); | ||
fse.outputFileSync("to-here/foo/eh.txt", "456"); | ||
}; | ||
const expectations = () => { | ||
// canada is copied | ||
path("from-here/foo/canada.txt").shouldBeFileWithContent("abc"); | ||
path("to-here/foo/canada.txt").shouldBeFileWithContent("abc"); | ||
// eh is not copied | ||
path("from-here/foo/eh.txt").shouldBeFileWithContent("123"); | ||
path("to-here/foo/eh.txt").shouldBeFileWithContent("456"); | ||
}; | ||
const overwrite = (srcInspectData, destInspectData) => { | ||
return new Promise((resolve, reject) => { | ||
jetpack | ||
.readAsync(srcInspectData.absolutePath) | ||
.then(data => { | ||
return data === "abc"; | ||
}) | ||
.then(resolve, reject); | ||
}); | ||
}; | ||
it("async", done => { | ||
preparations(); | ||
jetpack | ||
.copyAsync("from-here", "to-here", { overwrite }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe("filter what to copy", () => { | ||
describe("by simple pattern", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', '1'); | ||
fse.outputFileSync('dir/file.md', 'm1'); | ||
fse.outputFileSync('dir/a/file.txt', '2'); | ||
fse.outputFileSync('dir/a/file.md', 'm2'); | ||
fse.outputFileSync("dir/file.txt", "1"); | ||
fse.outputFileSync("dir/file.md", "m1"); | ||
fse.outputFileSync("dir/a/file.txt", "2"); | ||
fse.outputFileSync("dir/a/file.md", "m2"); | ||
}; | ||
const expectations = () => { | ||
path('copy/file.txt').shouldBeFileWithContent('1'); | ||
path('copy/file.md').shouldNotExist(); | ||
path('copy/a/file.txt').shouldBeFileWithContent('2'); | ||
path('copy/a/file.md').shouldNotExist(); | ||
path("copy/file.txt").shouldBeFileWithContent("1"); | ||
path("copy/file.md").shouldNotExist(); | ||
path("copy/a/file.txt").shouldBeFileWithContent("2"); | ||
path("copy/a/file.md").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('dir', 'copy', { matching: '*.txt' }); | ||
jetpack.copy("dir", "copy", { matching: "*.txt" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('dir', 'copy', { matching: '*.txt' }) | ||
.then(() => { | ||
jetpack.copyAsync("dir", "copy", { matching: "*.txt" }).then(() => { | ||
expectations(); | ||
@@ -329,52 +360,52 @@ done(); | ||
describe('by pattern anchored to copied directory', () => { | ||
describe("by pattern anchored to copied directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('x/y/dir/file.txt', '1'); | ||
fse.outputFileSync('x/y/dir/a/file.txt', '2'); | ||
fse.outputFileSync('x/y/dir/a/b/file.txt', '3'); | ||
fse.outputFileSync("x/y/dir/file.txt", "1"); | ||
fse.outputFileSync("x/y/dir/a/file.txt", "2"); | ||
fse.outputFileSync("x/y/dir/a/b/file.txt", "3"); | ||
}; | ||
const expectations = () => { | ||
path('copy/file.txt').shouldNotExist(); | ||
path('copy/a/file.txt').shouldBeFileWithContent('2'); | ||
path('copy/a/b/file.txt').shouldNotExist(); | ||
path("copy/file.txt").shouldNotExist(); | ||
path("copy/a/file.txt").shouldBeFileWithContent("2"); | ||
path("copy/a/b/file.txt").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('x/y/dir', 'copy', { matching: 'a/*.txt' }); | ||
jetpack.copy("x/y/dir", "copy", { matching: "a/*.txt" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('x/y/dir', 'copy', { matching: 'a/*.txt' }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}); | ||
jetpack | ||
.copyAsync("x/y/dir", "copy", { matching: "a/*.txt" }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('can use ./ as indication of anchor directory', () => { | ||
describe("can use ./ as indication of anchor directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('x/y/a.txt', '123'); | ||
fse.outputFileSync('x/y/b/a.txt', '456'); | ||
fse.outputFileSync("x/y/a.txt", "123"); | ||
fse.outputFileSync("x/y/b/a.txt", "456"); | ||
}; | ||
const expectations = () => { | ||
path('copy/a.txt').shouldBeFileWithContent('123'); | ||
path('copy/b/a.txt').shouldNotExist(); | ||
path("copy/a.txt").shouldBeFileWithContent("123"); | ||
path("copy/b/a.txt").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('x/y', 'copy', { matching: './a.txt' }); | ||
jetpack.copy("x/y", "copy", { matching: "./a.txt" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('x/y', 'copy', { matching: './a.txt' }) | ||
.then(() => { | ||
jetpack.copyAsync("x/y", "copy", { matching: "./a.txt" }).then(() => { | ||
expectations(); | ||
@@ -386,58 +417,59 @@ done(); | ||
describe('matching works also if copying single file', () => { | ||
describe("matching works also if copying single file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a', '123'); | ||
fse.outputFileSync('x', '456'); | ||
fse.outputFileSync("a", "123"); | ||
fse.outputFileSync("x", "456"); | ||
}; | ||
const expectations = () => { | ||
path('a-copy').shouldNotExist(); | ||
path('x-copy').shouldBeFileWithContent('456'); | ||
path("a-copy").shouldNotExist(); | ||
path("x-copy").shouldBeFileWithContent("456"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('a', 'a-copy', { matching: 'x' }); | ||
jetpack.copy('x', 'x-copy', { matching: 'x' }); | ||
jetpack.copy("a", "a-copy", { matching: "x" }); | ||
jetpack.copy("x", "x-copy", { matching: "x" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('a', 'a-copy', { matching: 'x' }) | ||
.then(() => { | ||
return jetpack.copyAsync('x', 'x-copy', { matching: 'x' }); | ||
}) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}); | ||
jetpack | ||
.copyAsync("a", "a-copy", { matching: "x" }) | ||
.then(() => { | ||
return jetpack.copyAsync("x", "x-copy", { matching: "x" }); | ||
}) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('can use negation in patterns', () => { | ||
describe("can use negation in patterns", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('x/y/dir/a/b'); | ||
fse.mkdirsSync('x/y/dir/a/x'); | ||
fse.mkdirsSync('x/y/dir/a/y'); | ||
fse.mkdirsSync('x/y/dir/a/z'); | ||
fse.mkdirsSync("x/y/dir/a/b"); | ||
fse.mkdirsSync("x/y/dir/a/x"); | ||
fse.mkdirsSync("x/y/dir/a/y"); | ||
fse.mkdirsSync("x/y/dir/a/z"); | ||
}; | ||
const expectations = () => { | ||
path('copy/dir/a/b').shouldBeDirectory(); | ||
path('copy/dir/a/x').shouldNotExist(); | ||
path('copy/dir/a/y').shouldNotExist(); | ||
path('copy/dir/a/z').shouldNotExist(); | ||
path("copy/dir/a/b").shouldBeDirectory(); | ||
path("copy/dir/a/x").shouldNotExist(); | ||
path("copy/dir/a/y").shouldNotExist(); | ||
path("copy/dir/a/z").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('x/y', 'copy', { | ||
jetpack.copy("x/y", "copy", { | ||
matching: [ | ||
'**', | ||
"**", | ||
// Three different pattern types to test: | ||
'!x', | ||
'!dir/a/y', | ||
'!./dir/a/z', | ||
], | ||
"!x", | ||
"!dir/a/y", | ||
"!./dir/a/z" | ||
] | ||
}); | ||
@@ -447,46 +479,46 @@ expectations(); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('x/y', 'copy', { | ||
matching: [ | ||
'**', | ||
// Three different pattern types to test: | ||
'!x', | ||
'!dir/a/y', | ||
'!./dir/a/z', | ||
], | ||
}) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}); | ||
jetpack | ||
.copyAsync("x/y", "copy", { | ||
matching: [ | ||
"**", | ||
// Three different pattern types to test: | ||
"!x", | ||
"!dir/a/y", | ||
"!./dir/a/z" | ||
] | ||
}) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('wildcard copies everything', () => { | ||
describe("wildcard copies everything", () => { | ||
const preparations = () => { | ||
// Just a file | ||
fse.outputFileSync('x/file.txt', '123'); | ||
fse.outputFileSync("x/file.txt", "123"); | ||
// Dot file | ||
fse.outputFileSync('x/y/.dot', 'dot'); | ||
fse.outputFileSync("x/y/.dot", "dot"); | ||
// Empty directory | ||
fse.mkdirsSync('x/y/z'); | ||
fse.mkdirsSync("x/y/z"); | ||
}; | ||
const expectations = () => { | ||
path('copy/file.txt').shouldBeFileWithContent('123'); | ||
path('copy/y/.dot').shouldBeFileWithContent('dot'); | ||
path('copy/y/z').shouldBeDirectory(); | ||
path("copy/file.txt").shouldBeFileWithContent("123"); | ||
path("copy/y/.dot").shouldBeFileWithContent("dot"); | ||
path("copy/y/z").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('x', 'copy', { matching: '**' }); | ||
jetpack.copy("x", "copy", { matching: "**" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('x', 'copy', { matching: '**' }) | ||
.then(() => { | ||
jetpack.copyAsync("x", "copy", { matching: "**" }).then(() => { | ||
expectations(); | ||
@@ -499,22 +531,23 @@ done(); | ||
describe('can copy symlink', () => { | ||
describe("can copy symlink", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('to_copy'); | ||
fse.symlinkSync('some/file', 'to_copy/symlink'); | ||
fse.mkdirsSync("to_copy"); | ||
fse.symlinkSync("some/file", "to_copy/symlink"); | ||
}; | ||
const expectations = () => { | ||
expect(fse.lstatSync('copied/symlink').isSymbolicLink()).to.equal(true); | ||
expect(fse.readlinkSync('copied/symlink')).to.equal(helper.osSep('some/file')); | ||
expect(fse.lstatSync("copied/symlink").isSymbolicLink()).to.equal(true); | ||
expect(fse.readlinkSync("copied/symlink")).to.equal( | ||
helper.osSep("some/file") | ||
); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('to_copy', 'copied'); | ||
jetpack.copy("to_copy", "copied"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('to_copy', 'copied') | ||
.then(() => { | ||
jetpack.copyAsync("to_copy", "copied").then(() => { | ||
expectations(); | ||
@@ -526,25 +559,26 @@ done(); | ||
describe('can overwrite symlink', () => { | ||
describe("can overwrite symlink", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('to_copy'); | ||
fse.symlinkSync('some/file', 'to_copy/symlink'); | ||
fse.mkdirsSync('copied'); | ||
fse.symlinkSync('some/other_file', 'copied/symlink'); | ||
fse.mkdirsSync("to_copy"); | ||
fse.symlinkSync("some/file", "to_copy/symlink"); | ||
fse.mkdirsSync("copied"); | ||
fse.symlinkSync("some/other_file", "copied/symlink"); | ||
}; | ||
const expectations = () => { | ||
expect(fse.lstatSync('copied/symlink').isSymbolicLink()).to.equal(true); | ||
expect(fse.readlinkSync('copied/symlink')).to.equal(helper.osSep('some/file')); | ||
expect(fse.lstatSync("copied/symlink").isSymbolicLink()).to.equal(true); | ||
expect(fse.readlinkSync("copied/symlink")).to.equal( | ||
helper.osSep("some/file") | ||
); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('to_copy', 'copied', { overwrite: true }); | ||
jetpack.copy("to_copy", "copied", { overwrite: true }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('to_copy', 'copied', { overwrite: true }) | ||
.then(() => { | ||
jetpack.copyAsync("to_copy", "copied", { overwrite: true }).then(() => { | ||
expectations(); | ||
@@ -556,25 +590,24 @@ done(); | ||
if (process.platform !== 'win32') { | ||
describe('copies also file permissions (unix only)', () => { | ||
if (process.platform !== "win32") { | ||
describe("copies also file permissions (unix only)", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.chmodSync('a/b', '700'); | ||
fse.chmodSync('a/b/c.txt', '711'); | ||
fse.outputFileSync("a/b/c.txt", "abc"); | ||
fse.chmodSync("a/b", "700"); | ||
fse.chmodSync("a/b/c.txt", "711"); | ||
}; | ||
const expectations = () => { | ||
path('x/b').shouldHaveMode('700'); | ||
path('x/b/c.txt').shouldHaveMode('711'); | ||
path("x/b").shouldHaveMode("700"); | ||
path("x/b/c.txt").shouldHaveMode("711"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.copy('a', 'x'); | ||
jetpack.copy("a", "x"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.copyAsync('a', 'x') | ||
.then(() => { | ||
jetpack.copyAsync("a", "x").then(() => { | ||
expectations(); | ||
@@ -587,14 +620,16 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.copy, methodName: 'copy' }, | ||
{ type: 'async', method: jetpack.copyAsync, methodName: 'copyAsync' }, | ||
{ type: "sync", method: jetpack.copy, methodName: "copy" }, | ||
{ type: "async", method: jetpack.copyAsync, methodName: "copyAsync" } | ||
]; | ||
describe('"from" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, 'xyz'); | ||
}).to.throw(`Argument "from" passed to ${test.methodName}(from, to, [options]) must be a string. Received undefined`); | ||
test.method(undefined, "xyz"); | ||
}).to.throw( | ||
`Argument "from" passed to ${test.methodName}(from, to, [options]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -605,7 +640,9 @@ }); | ||
describe('"to" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc'); | ||
}).to.throw(`Argument "to" passed to ${test.methodName}(from, to, [options]) must be a string. Received undefined`); | ||
test.method("abc"); | ||
}).to.throw( | ||
`Argument "to" passed to ${test.methodName}(from, to, [options]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -617,7 +654,9 @@ }); | ||
describe('"overwrite" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', 'xyz', { overwrite: 1 }); | ||
}).to.throw(`Argument "options.overwrite" passed to ${test.methodName}(from, to, [options]) must be a boolean or a function. Received number`); | ||
test.method("abc", "xyz", { overwrite: 1 }); | ||
}).to.throw( | ||
`Argument "options.overwrite" passed to ${test.methodName}(from, to, [options]) must be a boolean or a function. Received number` | ||
); | ||
}); | ||
@@ -627,7 +666,9 @@ }); | ||
describe('"matching" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', 'xyz', { matching: 1 }); | ||
}).to.throw(`Argument "options.matching" passed to ${test.methodName}(from, to, [options]) must be a string or an array of string. Received number`); | ||
test.method("abc", "xyz", { matching: 1 }); | ||
}).to.throw( | ||
`Argument "options.matching" passed to ${test.methodName}(from, to, [options]) must be a string or an array of string. Received number` | ||
); | ||
}); | ||
@@ -634,0 +675,0 @@ }); |
@@ -1,18 +0,18 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const expect = require('chai').expect; | ||
const jetpack = require('..'); | ||
const pathUtil = require("path"); | ||
const expect = require("chai").expect; | ||
const jetpack = require(".."); | ||
describe('cwd', () => { | ||
it('returns the same path as process.cwd for main instance of jetpack', () => { | ||
describe("cwd", () => { | ||
it("returns the same path as process.cwd for main instance of jetpack", () => { | ||
expect(jetpack.cwd()).to.equal(process.cwd()); | ||
}); | ||
it('can create new context with different cwd', () => { | ||
let jetCwd = jetpack.cwd('/'); // absolute path | ||
expect(jetCwd.cwd()).to.equal(pathUtil.resolve(process.cwd(), '/')); | ||
it("can create new context with different cwd", () => { | ||
let jetCwd = jetpack.cwd("/"); // absolute path | ||
expect(jetCwd.cwd()).to.equal(pathUtil.resolve(process.cwd(), "/")); | ||
jetCwd = jetpack.cwd('../..'); // relative path | ||
expect(jetCwd.cwd()).to.equal(pathUtil.resolve(process.cwd(), '../..')); | ||
jetCwd = jetpack.cwd("../.."); // relative path | ||
expect(jetCwd.cwd()).to.equal(pathUtil.resolve(process.cwd(), "../..")); | ||
@@ -22,14 +22,16 @@ expect(jetpack.cwd()).to.equal(process.cwd()); // cwd of main lib should be intact | ||
it('cwd contexts can be created recursively', () => { | ||
const jetCwd1 = jetpack.cwd('..'); | ||
expect(jetCwd1.cwd()).to.equal(pathUtil.resolve(process.cwd(), '..')); | ||
it("cwd contexts can be created recursively", () => { | ||
const jetCwd1 = jetpack.cwd(".."); | ||
expect(jetCwd1.cwd()).to.equal(pathUtil.resolve(process.cwd(), "..")); | ||
const jetCwd2 = jetCwd1.cwd('..'); | ||
expect(jetCwd2.cwd()).to.equal(pathUtil.resolve(process.cwd(), '../..')); | ||
const jetCwd2 = jetCwd1.cwd(".."); | ||
expect(jetCwd2.cwd()).to.equal(pathUtil.resolve(process.cwd(), "../..")); | ||
}); | ||
it('cwd can join path parts', () => { | ||
const jetCwd = jetpack.cwd('a', 'b', 'c'); | ||
expect(jetCwd.cwd()).to.equal(pathUtil.resolve(process.cwd(), 'a', 'b', 'c')); | ||
it("cwd can join path parts", () => { | ||
const jetCwd = jetpack.cwd("a", "b", "c"); | ||
expect(jetCwd.cwd()).to.equal( | ||
pathUtil.resolve(process.cwd(), "a", "b", "c") | ||
); | ||
}); | ||
}); |
@@ -1,11 +0,11 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const pathUtil = require('path'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const pathUtil = require("path"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('dir', () => { | ||
describe("dir", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
@@ -16,13 +16,12 @@ afterEach(helper.switchBackToCorrectCwd); | ||
const expectations = () => { | ||
path('x').shouldBeDirectory(); | ||
path("x").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
jetpack.dir('x'); | ||
it("sync", () => { | ||
jetpack.dir("x"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.dirAsync('x') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.dirAsync("x").then(() => { | ||
expectations(); | ||
@@ -34,21 +33,20 @@ done(); | ||
describe('does nothing if directory already exists', () => { | ||
describe("does nothing if directory already exists", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('x'); | ||
fse.mkdirsSync("x"); | ||
}; | ||
const expectations = () => { | ||
path('x').shouldBeDirectory(); | ||
path("x").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.dir('x'); | ||
jetpack.dir("x"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.dirAsync('x') | ||
.then(() => { | ||
jetpack.dirAsync("x").then(() => { | ||
expectations(); | ||
@@ -60,15 +58,14 @@ done(); | ||
describe('creates nested directories if necessary', () => { | ||
describe("creates nested directories if necessary", () => { | ||
const expectations = () => { | ||
path('a/b/c').shouldBeDirectory(); | ||
path("a/b/c").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
jetpack.dir('a/b/c'); | ||
it("sync", () => { | ||
jetpack.dir("a/b/c"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.dirAsync('a/b/c') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.dirAsync("a/b/c").then(() => { | ||
expectations(); | ||
@@ -80,8 +77,8 @@ done(); | ||
describe('handles well two calls racing to create the same directory', () => { | ||
describe("handles well two calls racing to create the same directory", () => { | ||
const expectations = () => { | ||
path('a/b/c').shouldBeDirectory(); | ||
path("a/b/c").shouldBeDirectory(); | ||
}; | ||
it('async', (done) => { | ||
it("async", done => { | ||
let doneCount = 0; | ||
@@ -95,4 +92,4 @@ const check = () => { | ||
}; | ||
jetpack.dirAsync('a/b/c').then(check); | ||
jetpack.dirAsync('a/b/c').then(check); | ||
jetpack.dirAsync("a/b/c").then(check); | ||
jetpack.dirAsync("a/b/c").then(check); | ||
}); | ||
@@ -103,21 +100,20 @@ }); | ||
const preparations = () => { | ||
fse.mkdirsSync('a/b'); | ||
fse.outputFileSync('a/c.txt', 'abc'); | ||
fse.mkdirsSync("a/b"); | ||
fse.outputFileSync("a/c.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b').shouldBeDirectory(); | ||
path('a/c.txt').shouldBeFileWithContent('abc'); | ||
path("a/b").shouldBeDirectory(); | ||
path("a/c.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.dir('a'); | ||
jetpack.dir("a"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.dirAsync('a') | ||
.then(() => { | ||
jetpack.dirAsync("a").then(() => { | ||
expectations(); | ||
@@ -129,22 +125,21 @@ done(); | ||
describe('makes directory empty if that option specified', () => { | ||
describe("makes directory empty if that option specified", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/file.txt', 'abc'); | ||
fse.outputFileSync("a/b/file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b/file.txt').shouldNotExist(); | ||
path('a').shouldBeDirectory(); | ||
path("a/b/file.txt").shouldNotExist(); | ||
path("a").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.dir('a', { empty: true }); | ||
jetpack.dir("a", { empty: true }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.dirAsync('a', { empty: true }) | ||
.then(() => { | ||
jetpack.dirAsync("a", { empty: true }).then(() => { | ||
expectations(); | ||
@@ -156,16 +151,16 @@ done(); | ||
describe('throws if given path is something other than directory', () => { | ||
describe("throws if given path is something other than directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a', 'abc'); | ||
fse.outputFileSync("a", "abc"); | ||
}; | ||
const expectations = (err) => { | ||
expect(err.message).to.have.string('exists but is not a directory'); | ||
const expectations = err => { | ||
expect(err.message).to.have.string("exists but is not a directory"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.dir('a'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.dir("a"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -176,6 +171,5 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.dirAsync('a') | ||
.catch((err) => { | ||
jetpack.dirAsync("a").catch(err => { | ||
expectations(err); | ||
@@ -187,17 +181,16 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const expectations = () => { | ||
path('a/b').shouldBeDirectory(); | ||
path("a/b").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
jetContext.dir('b'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
jetContext.dir("b"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
jetContext.dirAsync('b') | ||
.then(() => { | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
jetContext.dirAsync("b").then(() => { | ||
expectations(); | ||
@@ -209,14 +202,13 @@ done(); | ||
describe('returns jetack instance pointing on this directory', () => { | ||
const expectations = (jetpackContext) => { | ||
expect(jetpackContext.cwd()).to.equal(pathUtil.resolve('a')); | ||
describe("returns jetack instance pointing on this directory", () => { | ||
const expectations = jetpackContext => { | ||
expect(jetpackContext.cwd()).to.equal(pathUtil.resolve("a")); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.dir('a')); | ||
it("sync", () => { | ||
expectations(jetpack.dir("a")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.dirAsync('a') | ||
.then((jetpackContext) => { | ||
it("async", done => { | ||
jetpack.dirAsync("a").then(jetpackContext => { | ||
expectations(jetpackContext); | ||
@@ -228,22 +220,20 @@ done(); | ||
if (process.platform !== 'win32') { | ||
describe('sets mode to newly created directory (unix only)', () => { | ||
if (process.platform !== "win32") { | ||
describe("sets mode to newly created directory (unix only)", () => { | ||
const expectations = () => { | ||
path('a').shouldHaveMode('511'); | ||
path("a").shouldHaveMode("511"); | ||
}; | ||
it('sync, mode passed as string', () => { | ||
jetpack.dir('a', { mode: '511' }); | ||
it("sync, mode passed as string", () => { | ||
jetpack.dir("a", { mode: "511" }); | ||
expectations(); | ||
}); | ||
it('sync, mode passed as number', () => { | ||
jetpack.dir('a', { mode: 0o511 }); | ||
it("sync, mode passed as number", () => { | ||
jetpack.dir("a", { mode: 0o511 }); | ||
expectations(); | ||
}); | ||
it('async, mode passed as string', (done) => { | ||
jetpack.dirAsync('a', { mode: '511' }) | ||
.then(() => { | ||
it("async, mode passed as string", done => { | ||
jetpack.dirAsync("a", { mode: "511" }).then(() => { | ||
expectations(); | ||
@@ -254,5 +244,4 @@ done(); | ||
it('async, mode passed as number', (done) => { | ||
jetpack.dirAsync('a', { mode: 0o511 }) | ||
.then(() => { | ||
it("async, mode passed as number", done => { | ||
jetpack.dirAsync("a", { mode: 0o511 }).then(() => { | ||
expectations(); | ||
@@ -264,16 +253,15 @@ done(); | ||
describe('sets desired mode to every created directory (unix only)', () => { | ||
describe("sets desired mode to every created directory (unix only)", () => { | ||
const expectations = () => { | ||
path('a').shouldHaveMode('711'); | ||
path('a/b').shouldHaveMode('711'); | ||
path("a").shouldHaveMode("711"); | ||
path("a/b").shouldHaveMode("711"); | ||
}; | ||
it('sync', () => { | ||
jetpack.dir('a/b', { mode: '711' }); | ||
it("sync", () => { | ||
jetpack.dir("a/b", { mode: "711" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.dirAsync('a/b', { mode: '711' }) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.dirAsync("a/b", { mode: "711" }).then(() => { | ||
expectations(); | ||
@@ -285,20 +273,19 @@ done(); | ||
describe('changes mode of existing directory to desired (unix only)', () => { | ||
describe("changes mode of existing directory to desired (unix only)", () => { | ||
const preparations = () => { | ||
fse.mkdirSync('a', '777'); | ||
fse.mkdirSync("a", "777"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldHaveMode('511'); | ||
path("a").shouldHaveMode("511"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.dir('a', { mode: '511' }); | ||
jetpack.dir("a", { mode: "511" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.dirAsync('a', { mode: '511' }) | ||
.then(() => { | ||
jetpack.dirAsync("a", { mode: "511" }).then(() => { | ||
expectations(); | ||
@@ -310,21 +297,20 @@ done(); | ||
describe('leaves mode of directory intact by default (unix only)', () => { | ||
describe("leaves mode of directory intact by default (unix only)", () => { | ||
const preparations = () => { | ||
fse.mkdirSync('a', '700'); | ||
fse.mkdirSync("a", "700"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldHaveMode('700'); | ||
path("a").shouldHaveMode("700"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.dir('a'); | ||
jetpack.dir("a"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.dirAsync('a') | ||
.then(() => { | ||
jetpack.dirAsync("a").then(() => { | ||
expectations(); | ||
@@ -336,15 +322,14 @@ done(); | ||
} else { | ||
describe('specyfying mode have no effect and throws no error (windows only)', () => { | ||
describe("specyfying mode have no effect and throws no error (windows only)", () => { | ||
const expectations = () => { | ||
path('x').shouldBeDirectory(); | ||
path("x").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
jetpack.dir('x', { mode: '511' }); | ||
it("sync", () => { | ||
jetpack.dir("x", { mode: "511" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.dirAsync('x', { mode: '511' }) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.dirAsync("x", { mode: "511" }).then(() => { | ||
expectations(); | ||
@@ -357,14 +342,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.dir, methodName: 'dir' }, | ||
{ type: 'async', method: jetpack.dirAsync, methodName: 'dirAsync' }, | ||
{ type: "sync", method: jetpack.dir, methodName: "dir" }, | ||
{ type: "async", method: jetpack.dirAsync, methodName: "dirAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, [criteria]) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -376,7 +365,11 @@ }); | ||
describe('"empty" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { empty: 1 }); | ||
}).to.throw(`Argument "criteria.empty" passed to ${test.methodName}(path, [criteria]) must be a boolean. Received number`); | ||
test.method("abc", { empty: 1 }); | ||
}).to.throw( | ||
`Argument "criteria.empty" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -386,7 +379,11 @@ }); | ||
describe('"mode" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { mode: true }); | ||
}).to.throw(`Argument "criteria.mode" passed to ${test.methodName}(path, [criteria]) must be a string or a number. Received boolean`); | ||
test.method("abc", { mode: true }); | ||
}).to.throw( | ||
`Argument "criteria.mode" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a string or a number. Received boolean` | ||
); | ||
}); | ||
@@ -393,0 +390,0 @@ }); |
@@ -1,9 +0,9 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('exists', () => { | ||
describe("exists", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
@@ -13,13 +13,12 @@ afterEach(helper.switchBackToCorrectCwd); | ||
describe("returns false if file doesn't exist", () => { | ||
const expectations = (exists) => { | ||
const expectations = exists => { | ||
expect(exists).to.equal(false); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.exists('file.txt')); | ||
it("sync", () => { | ||
expectations(jetpack.exists("file.txt")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.existsAsync('file.txt') | ||
.then((exists) => { | ||
it("async", done => { | ||
jetpack.existsAsync("file.txt").then(exists => { | ||
expectations(exists); | ||
@@ -33,18 +32,17 @@ done(); | ||
const preparations = () => { | ||
fse.mkdirsSync('a'); | ||
fse.mkdirsSync("a"); | ||
}; | ||
const expectations = (exists) => { | ||
expect(exists).to.equal('dir'); | ||
const expectations = exists => { | ||
expect(exists).to.equal("dir"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.exists('a')); | ||
expectations(jetpack.exists("a")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.existsAsync('a') | ||
.then((exists) => { | ||
jetpack.existsAsync("a").then(exists => { | ||
expectations(exists); | ||
@@ -58,18 +56,17 @@ done(); | ||
const preparations = () => { | ||
fse.outputFileSync('text.txt', 'abc'); | ||
fse.outputFileSync("text.txt", "abc"); | ||
}; | ||
const expectations = (exists) => { | ||
expect(exists).to.equal('file'); | ||
const expectations = exists => { | ||
expect(exists).to.equal("file"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.exists('text.txt')); | ||
expectations(jetpack.exists("text.txt")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.existsAsync('text.txt') | ||
.then((exists) => { | ||
jetpack.existsAsync("text.txt").then(exists => { | ||
expectations(exists); | ||
@@ -81,22 +78,21 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/text.txt', 'abc'); | ||
fse.outputFileSync("a/text.txt", "abc"); | ||
}; | ||
const expectations = (exists) => { | ||
expect(exists).to.equal('file'); | ||
const expectations = exists => { | ||
expect(exists).to.equal("file"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
expectations(jetContext.exists('text.txt')); | ||
expectations(jetContext.exists("text.txt")); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.existsAsync('text.txt') | ||
.then((exists) => { | ||
jetContext.existsAsync("text.txt").then(exists => { | ||
expectations(exists); | ||
@@ -108,14 +104,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.exists, methodName: 'exists' }, | ||
{ type: 'async', method: jetpack.existsAsync, methodName: 'existsAsync' }, | ||
{ type: "sync", method: jetpack.exists, methodName: "exists" }, | ||
{ type: "async", method: jetpack.existsAsync, methodName: "existsAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -122,0 +122,0 @@ }); |
@@ -1,10 +0,10 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('file', () => { | ||
describe("file", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
@@ -15,122 +15,127 @@ afterEach(helper.switchBackToCorrectCwd); | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent(''); | ||
path("file.txt").shouldBeFileWithContent(""); | ||
}; | ||
it('sync', () => { | ||
jetpack.file('file.txt'); | ||
it("sync", () => { | ||
jetpack.file("file.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('file.txt') | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("file.txt") | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('leaves file intact if it already exists', () => { | ||
describe("leaves file intact if it already exists", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', 'abc'); | ||
fse.outputFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('abc'); | ||
path("file.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.file('file.txt'); | ||
jetpack.file("file.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.fileAsync('file.txt') | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.fileAsync("file.txt") | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('can save file content given as string', () => { | ||
describe("can save file content given as string", () => { | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('ąbć'); | ||
path("file.txt").shouldBeFileWithContent("ąbć"); | ||
}; | ||
it('sync', () => { | ||
jetpack.file('file.txt', { content: 'ąbć' }); | ||
it("sync", () => { | ||
jetpack.file("file.txt", { content: "ąbć" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('file.txt', { content: 'ąbć' }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("file.txt", { content: "ąbć" }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('can save file content given as buffer', () => { | ||
describe("can save file content given as buffer", () => { | ||
const expectations = () => { | ||
path('file').shouldBeFileWithContent(new Buffer([11, 22])); | ||
path("file").shouldBeFileWithContent(new Buffer([11, 22])); | ||
}; | ||
it('sync', () => { | ||
jetpack.file('file', { content: new Buffer([11, 22]) }); | ||
it("sync", () => { | ||
jetpack.file("file", { content: new Buffer([11, 22]) }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('file', { content: new Buffer([11, 22]) }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("file", { content: new Buffer([11, 22]) }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('can save file content given as plain JS object (will be saved as JSON)', () => { | ||
describe("can save file content given as plain JS object (will be saved as JSON)", () => { | ||
const obj = { | ||
a: 'abc', | ||
b: 123, | ||
a: "abc", | ||
b: 123 | ||
}; | ||
const expectations = () => { | ||
const data = JSON.parse(fse.readFileSync('file.txt', 'utf8')); | ||
const data = JSON.parse(fse.readFileSync("file.txt", "utf8")); | ||
expect(data).to.eql(obj); | ||
}; | ||
it('sync', () => { | ||
jetpack.file('file.txt', { content: obj }); | ||
it("sync", () => { | ||
jetpack.file("file.txt", { content: obj }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('file.txt', { content: obj }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("file.txt", { content: obj }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('written JSON data can be indented', () => { | ||
describe("written JSON data can be indented", () => { | ||
const obj = { | ||
a: 'abc', | ||
b: 123, | ||
a: "abc", | ||
b: 123 | ||
}; | ||
const expectations = () => { | ||
const sizeA = fse.statSync('a.json').size; | ||
const sizeB = fse.statSync('b.json').size; | ||
const sizeC = fse.statSync('c.json').size; | ||
const sizeA = fse.statSync("a.json").size; | ||
const sizeB = fse.statSync("b.json").size; | ||
const sizeC = fse.statSync("c.json").size; | ||
expect(sizeB).to.be.above(sizeA); | ||
@@ -140,65 +145,67 @@ expect(sizeC).to.be.above(sizeB); | ||
it('sync', () => { | ||
jetpack.file('a.json', { content: obj, jsonIndent: 0 }); | ||
jetpack.file('b.json', { content: obj }); // Default indent = 2 | ||
jetpack.file('c.json', { content: obj, jsonIndent: 4 }); | ||
it("sync", () => { | ||
jetpack.file("a.json", { content: obj, jsonIndent: 0 }); | ||
jetpack.file("b.json", { content: obj }); // Default indent = 2 | ||
jetpack.file("c.json", { content: obj, jsonIndent: 4 }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('a.json', { content: obj, jsonIndent: 0 }) | ||
.then(() => { | ||
return jetpack.fileAsync('b.json', { content: obj }); // Default indent = 2 | ||
}) | ||
.then(() => { | ||
return jetpack.fileAsync('c.json', { content: obj, jsonIndent: 4 }); | ||
}) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("a.json", { content: obj, jsonIndent: 0 }) | ||
.then(() => { | ||
return jetpack.fileAsync("b.json", { content: obj }); // Default indent = 2 | ||
}) | ||
.then(() => { | ||
return jetpack.fileAsync("c.json", { content: obj, jsonIndent: 4 }); | ||
}) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('replaces content of already existing file', () => { | ||
describe("replaces content of already existing file", () => { | ||
const preparations = () => { | ||
fse.writeFileSync('file.txt', 'abc'); | ||
fse.writeFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('123'); | ||
path("file.txt").shouldBeFileWithContent("123"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.file('file.txt', { content: '123' }); | ||
jetpack.file("file.txt", { content: "123" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.fileAsync('file.txt', { content: '123' }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.fileAsync("file.txt", { content: "123" }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('throws if given path is not a file', () => { | ||
describe("throws if given path is not a file", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('a'); | ||
fse.mkdirsSync("a"); | ||
}; | ||
const expectations = (err) => { | ||
expect(err.message).to.have.string('exists but is not a file.'); | ||
const expectations = err => { | ||
expect(err.message).to.have.string("exists but is not a file."); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.file('a'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.file("a"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -209,10 +216,11 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.fileAsync('a') | ||
.catch((err) => { | ||
expectations(err); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.fileAsync("a") | ||
.catch(err => { | ||
expectations(err); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
@@ -223,93 +231,98 @@ }); | ||
const expectations = () => { | ||
path('a/b/c.txt').shouldBeFileWithContent(''); | ||
path("a/b/c.txt").shouldBeFileWithContent(""); | ||
}; | ||
it('sync', () => { | ||
jetpack.file('a/b/c.txt'); | ||
it("sync", () => { | ||
jetpack.file("a/b/c.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('a/b/c.txt') | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("a/b/c.txt") | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('returns currently used jetpack instance', () => { | ||
const expectations = (jetpackContext) => { | ||
describe("returns currently used jetpack instance", () => { | ||
const expectations = jetpackContext => { | ||
expect(jetpackContext).to.equal(jetpack); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.file('file.txt')); | ||
it("sync", () => { | ||
expectations(jetpack.file("file.txt")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('file.txt') | ||
.then((jetpackContext) => { | ||
expectations(jetpackContext); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("file.txt") | ||
.then(jetpackContext => { | ||
expectations(jetpackContext); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const expectations = () => { | ||
path('a/b.txt').shouldBeFileWithContent(''); | ||
path("a/b.txt").shouldBeFileWithContent(""); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
jetContext.file('b.txt'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
jetContext.file("b.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
jetContext.fileAsync('b.txt') | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
jetContext | ||
.fileAsync("b.txt") | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
if (process.platform !== 'win32') { | ||
describe('sets mode of newly created file (unix only)', () => { | ||
if (process.platform !== "win32") { | ||
describe("sets mode of newly created file (unix only)", () => { | ||
const expectations = () => { | ||
path('file.txt').shouldHaveMode('711'); | ||
path("file.txt").shouldHaveMode("711"); | ||
}; | ||
it('sync, mode passed as string', () => { | ||
jetpack.file('file.txt', { mode: '711' }); | ||
it("sync, mode passed as string", () => { | ||
jetpack.file("file.txt", { mode: "711" }); | ||
expectations(); | ||
}); | ||
it('sync, mode passed as number', () => { | ||
jetpack.file('file.txt', { mode: 0o711 }); | ||
it("sync, mode passed as number", () => { | ||
jetpack.file("file.txt", { mode: 0o711 }); | ||
expectations(); | ||
}); | ||
it('async, mode passed as string', (done) => { | ||
jetpack.fileAsync('file.txt', { mode: '711' }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async, mode passed as string", done => { | ||
jetpack | ||
.fileAsync("file.txt", { mode: "711" }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
it('async, mode passed as number', (done) => { | ||
jetpack.fileAsync('file.txt', { mode: 0o711 }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async, mode passed as number", done => { | ||
jetpack | ||
.fileAsync("file.txt", { mode: 0o711 }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
@@ -320,79 +333,83 @@ }); | ||
const preparations = () => { | ||
fse.writeFileSync('file.txt', 'abc', { mode: '700' }); | ||
fse.writeFileSync("file.txt", "abc", { mode: "700" }); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldHaveMode('511'); | ||
path("file.txt").shouldHaveMode("511"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.file('file.txt', { mode: '511' }); | ||
jetpack.file("file.txt", { mode: "511" }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.fileAsync('file.txt', { mode: '511' }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.fileAsync("file.txt", { mode: "511" }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('leaves mode of file intact if not explicitly specified (unix only)', () => { | ||
describe("leaves mode of file intact if not explicitly specified (unix only)", () => { | ||
const preparations = () => { | ||
fse.writeFileSync('file.txt', 'abc', { mode: '700' }); | ||
fse.writeFileSync("file.txt", "abc", { mode: "700" }); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldHaveMode('700'); | ||
path("file.txt").shouldHaveMode("700"); | ||
}; | ||
it('sync, ensure exists', () => { | ||
it("sync, ensure exists", () => { | ||
preparations(); | ||
jetpack.file('file.txt'); | ||
jetpack.file("file.txt"); | ||
expectations(); | ||
}); | ||
it('sync, ensure content', () => { | ||
it("sync, ensure content", () => { | ||
preparations(); | ||
jetpack.file('file.txt', { content: 'abc' }); | ||
jetpack.file("file.txt", { content: "abc" }); | ||
expectations(); | ||
}); | ||
it('async, ensure exists', (done) => { | ||
it("async, ensure exists", done => { | ||
preparations(); | ||
jetpack.fileAsync('file.txt') | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.fileAsync("file.txt") | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
it('async, ensure content', (done) => { | ||
it("async, ensure content", done => { | ||
preparations(); | ||
jetpack.fileAsync('file.txt', { content: 'abc' }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.fileAsync("file.txt", { content: "abc" }) | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
} else { | ||
describe('specyfying mode have no effect and throws no error (windows only)', () => { | ||
it('sync', () => { | ||
jetpack.file('file.txt', { mode: '711' }); | ||
describe("specyfying mode have no effect and throws no error (windows only)", () => { | ||
it("sync", () => { | ||
jetpack.file("file.txt", { mode: "711" }); | ||
}); | ||
it('async', (done) => { | ||
jetpack.fileAsync('file.txt', { mode: '711' }) | ||
.then(() => { | ||
done(); | ||
}) | ||
.catch(done); | ||
it("async", done => { | ||
jetpack | ||
.fileAsync("file.txt", { mode: "711" }) | ||
.then(() => { | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
@@ -402,14 +419,18 @@ }); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.file, methodName: 'file' }, | ||
{ type: 'async', method: jetpack.fileAsync, methodName: 'fileAsync' }, | ||
{ type: "sync", method: jetpack.file, methodName: "file" }, | ||
{ type: "async", method: jetpack.fileAsync, methodName: "fileAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, [criteria]) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -421,7 +442,11 @@ }); | ||
describe('"content" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { content: 1 }); | ||
}).to.throw(`Argument "criteria.content" passed to ${test.methodName}(path, [criteria]) must be a string or a buffer or an object or an array. Received number`); | ||
test.method("abc", { content: 1 }); | ||
}).to.throw( | ||
`Argument "criteria.content" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a string or a buffer or an object or an array. Received number` | ||
); | ||
}); | ||
@@ -431,7 +456,11 @@ }); | ||
describe('"jsonIndent" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { jsonIndent: true }); | ||
}).to.throw(`Argument "criteria.jsonIndent" passed to ${test.methodName}(path, [criteria]) must be a number. Received boolean`); | ||
test.method("abc", { jsonIndent: true }); | ||
}).to.throw( | ||
`Argument "criteria.jsonIndent" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a number. Received boolean` | ||
); | ||
}); | ||
@@ -441,7 +470,11 @@ }); | ||
describe('"mode" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { mode: true }); | ||
}).to.throw(`Argument "criteria.mode" passed to ${test.methodName}(path, [criteria]) must be a string or a number. Received boolean`); | ||
test.method("abc", { mode: true }); | ||
}).to.throw( | ||
`Argument "criteria.mode" passed to ${ | ||
test.methodName | ||
}(path, [criteria]) must be a string or a number. Received boolean` | ||
); | ||
}); | ||
@@ -448,0 +481,0 @@ }); |
@@ -1,31 +0,30 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('find', () => { | ||
describe("find", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('returns list of relative paths anchored to CWD', () => { | ||
describe("returns list of relative paths anchored to CWD", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/file.txt', 'abc'); | ||
fse.outputFileSync("a/b/file.txt", "abc"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['a/b/file.txt']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["a/b/file.txt"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { matching: '*.txt' })); | ||
expectations(jetpack.find("a", { matching: "*.txt" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { matching: '*.txt' }) | ||
.then((found) => { | ||
jetpack.findAsync("a", { matching: "*.txt" }).then(found => { | ||
expectations(found); | ||
@@ -37,48 +36,48 @@ done(); | ||
describe('if recursive=false will exclude subfolders from search', () => { | ||
describe("if recursive=false will exclude subfolders from search", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('x/file.txt', 'abc'); | ||
fse.outputFileSync('x/y/file.txt', '123'); | ||
fse.outputFileSync('x/y/b/file.txt', '456'); | ||
fse.outputFileSync("x/file.txt", "abc"); | ||
fse.outputFileSync("x/y/file.txt", "123"); | ||
fse.outputFileSync("x/y/b/file.txt", "456"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['x/file.txt']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["x/file.txt"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('x', { matching: '*.txt', recursive: false })); | ||
expectations(jetpack.find("x", { matching: "*.txt", recursive: false })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('x', { matching: '*.txt', recursive: false }) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}); | ||
jetpack | ||
.findAsync("x", { matching: "*.txt", recursive: false }) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('defaults to CWD if no path provided', () => { | ||
describe("defaults to CWD if no path provided", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/file.txt', 'abc'); | ||
fse.outputFileSync("a/b/file.txt", "abc"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['a/b/file.txt']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["a/b/file.txt"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find({ matching: '*.txt' })); | ||
expectations(jetpack.find({ matching: "*.txt" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync({ matching: '*.txt' }) | ||
.then((found) => { | ||
jetpack.findAsync({ matching: "*.txt" }).then(found => { | ||
expectations(found); | ||
@@ -90,20 +89,19 @@ done(); | ||
describe('returns empty list if nothing found', () => { | ||
describe("returns empty list if nothing found", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.md', 'abc'); | ||
fse.outputFileSync("a/b/c.md", "abc"); | ||
}; | ||
const expectations = (found) => { | ||
const expectations = found => { | ||
expect(found).to.eql([]); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { matching: '*.txt' })); | ||
expectations(jetpack.find("a", { matching: "*.txt" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { matching: '*.txt' }) | ||
.then((found) => { | ||
jetpack.findAsync("a", { matching: "*.txt" }).then(found => { | ||
expectations(found); | ||
@@ -115,15 +113,15 @@ done(); | ||
describe('finds all paths which match globs', () => { | ||
describe("finds all paths which match globs", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/file.txt', '1'); | ||
fse.outputFileSync('a/b/c/file.txt', '2'); | ||
fse.outputFileSync('a/b/c/file.md', '3'); | ||
fse.outputFileSync('a/x/y/z', 'Zzzzz...'); | ||
fse.outputFileSync("a/b/file.txt", "1"); | ||
fse.outputFileSync("a/b/c/file.txt", "2"); | ||
fse.outputFileSync("a/b/c/file.md", "3"); | ||
fse.outputFileSync("a/x/y/z", "Zzzzz..."); | ||
}; | ||
const expectations = (found) => { | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep([ | ||
'a/b/c/file.txt', | ||
'a/b/file.txt', | ||
'a/x/y/z', | ||
"a/b/c/file.txt", | ||
"a/b/file.txt", | ||
"a/x/y/z" | ||
]); | ||
@@ -134,11 +132,10 @@ found.sort(); | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { matching: ['*.txt', 'z'] })); | ||
expectations(jetpack.find("a", { matching: ["*.txt", "z"] })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { matching: ['*.txt', 'z'] }) | ||
.then((found) => { | ||
jetpack.findAsync("a", { matching: ["*.txt", "z"] }).then(found => { | ||
expectations(found); | ||
@@ -152,20 +149,19 @@ done(); | ||
const preparations = () => { | ||
fse.outputFileSync('x/y/a/b/file.txt', '123'); | ||
fse.outputFileSync('x/y/a/b/c/file.txt', '456'); | ||
fse.outputFileSync("x/y/a/b/file.txt", "123"); | ||
fse.outputFileSync("x/y/a/b/c/file.txt", "456"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['x/y/a/b/file.txt']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["x/y/a/b/file.txt"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('x/y/a', { matching: 'b/*.txt' })); | ||
expectations(jetpack.find("x/y/a", { matching: "b/*.txt" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('x/y/a', { matching: 'b/*.txt' }) | ||
.then((found) => { | ||
jetpack.findAsync("x/y/a", { matching: "b/*.txt" }).then(found => { | ||
expectations(found); | ||
@@ -177,22 +173,21 @@ done(); | ||
describe('can use ./ as indication of anchor directory', () => { | ||
describe("can use ./ as indication of anchor directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('x/y/file.txt', '123'); | ||
fse.outputFileSync('x/y/b/file.txt', '456'); | ||
fse.outputFileSync("x/y/file.txt", "123"); | ||
fse.outputFileSync("x/y/b/file.txt", "456"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['x/y/file.txt']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["x/y/file.txt"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('x/y', { matching: './file.txt' })); | ||
expectations(jetpack.find("x/y", { matching: "./file.txt" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('x/y', { matching: './file.txt' }) | ||
.then((found) => { | ||
jetpack.findAsync("x/y", { matching: "./file.txt" }).then(found => { | ||
expectations(found); | ||
@@ -204,43 +199,46 @@ done(); | ||
describe('deals with negation globs', () => { | ||
describe("deals with negation globs", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('x/y/a/b', 'bbb'); | ||
fse.outputFileSync('x/y/a/x', 'xxx'); | ||
fse.outputFileSync('x/y/a/y', 'yyy'); | ||
fse.outputFileSync('x/y/a/z', 'zzz'); | ||
fse.outputFileSync("x/y/a/b", "bbb"); | ||
fse.outputFileSync("x/y/a/x", "xxx"); | ||
fse.outputFileSync("x/y/a/y", "yyy"); | ||
fse.outputFileSync("x/y/a/z", "zzz"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['x/y/a/b']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["x/y/a/b"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('x/y', { | ||
matching: [ | ||
'a/*', | ||
// Three different pattern types to test: | ||
'!x', | ||
'!a/y', | ||
'!./a/z', | ||
], | ||
})); | ||
expectations( | ||
jetpack.find("x/y", { | ||
matching: [ | ||
"a/*", | ||
// Three different pattern types to test: | ||
"!x", | ||
"!a/y", | ||
"!./a/z" | ||
] | ||
}) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('x/y', { | ||
matching: [ | ||
'a/*', | ||
// Three different pattern types to test: | ||
'!x', | ||
'!a/y', | ||
'!./a/z', | ||
], | ||
}) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}); | ||
jetpack | ||
.findAsync("x/y", { | ||
matching: [ | ||
"a/*", | ||
// Three different pattern types to test: | ||
"!x", | ||
"!a/y", | ||
"!./a/z" | ||
] | ||
}) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}); | ||
}); | ||
@@ -251,20 +249,19 @@ }); | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/foo1', 'abc'); | ||
fse.mkdirsSync('a/b/foo2'); | ||
fse.outputFileSync("a/b/foo1", "abc"); | ||
fse.mkdirsSync("a/b/foo2"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['a/b/foo1']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["a/b/foo1"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { matching: 'foo*' })); | ||
expectations(jetpack.find("a", { matching: "foo*" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { matching: 'foo*' }) | ||
.then((found) => { | ||
jetpack.findAsync("a", { matching: "foo*" }).then(found => { | ||
expectations(found); | ||
@@ -278,21 +275,20 @@ done(); | ||
const preparations = () => { | ||
fse.outputFileSync('file', 'abc'); | ||
fse.mkdirsSync('dir'); | ||
jetpack.symlink('file', 'symfile'); | ||
jetpack.symlink('dir', 'symdir'); | ||
fse.outputFileSync("file", "abc"); | ||
fse.mkdirsSync("dir"); | ||
jetpack.symlink("file", "symfile"); | ||
jetpack.symlink("dir", "symdir"); | ||
}; | ||
const expectations = (found) => { | ||
expect(found).to.eql(['file']); | ||
const expectations = found => { | ||
expect(found).to.eql(["file"]); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find({ matching: '*' })); | ||
expectations(jetpack.find({ matching: "*" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync({ matching: '*' }) | ||
.then((found) => { | ||
jetpack.findAsync({ matching: "*" }).then(found => { | ||
expectations(found); | ||
@@ -304,157 +300,168 @@ done(); | ||
describe('can look for files and directories', () => { | ||
describe("can look for files and directories", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/foo1', 'abc'); | ||
fse.mkdirsSync('a/b/foo2'); | ||
fse.outputFileSync("a/b/foo1", "abc"); | ||
fse.mkdirsSync("a/b/foo2"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['a/b/foo1', 'a/b/foo2']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["a/b/foo1", "a/b/foo2"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { | ||
matching: 'foo*', | ||
directories: true, | ||
})); | ||
expectations( | ||
jetpack.find("a", { | ||
matching: "foo*", | ||
directories: true | ||
}) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { | ||
matching: 'foo*', | ||
directories: true, | ||
}) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.findAsync("a", { | ||
matching: "foo*", | ||
directories: true | ||
}) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('can look for only directories', () => { | ||
describe("can look for only directories", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/foo1', 'abc'); | ||
fse.mkdirsSync('a/b/foo2'); | ||
fse.outputFileSync("a/b/foo1", "abc"); | ||
fse.mkdirsSync("a/b/foo2"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['a/b/foo2']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["a/b/foo2"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { | ||
matching: 'foo*', | ||
files: false, | ||
directories: true, | ||
})); | ||
expectations( | ||
jetpack.find("a", { | ||
matching: "foo*", | ||
files: false, | ||
directories: true | ||
}) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { | ||
matching: 'foo*', | ||
files: false, | ||
directories: true, | ||
}) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.findAsync("a", { | ||
matching: "foo*", | ||
files: false, | ||
directories: true | ||
}) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('looking for directories works ok with only negation globs in set', () => { | ||
describe("looking for directories works ok with only negation globs in set", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/x', '123'); | ||
fse.outputFileSync('a/y', '789'); | ||
fse.outputFileSync("a/x", "123"); | ||
fse.outputFileSync("a/y", "789"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['a/x']); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["a/x"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { | ||
matching: ['!y'], | ||
directories: true, | ||
})); | ||
expectations( | ||
jetpack.find("a", { | ||
matching: ["!y"], | ||
directories: true | ||
}) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { | ||
matching: ['!y'], | ||
directories: true, | ||
}) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.findAsync("a", { | ||
matching: ["!y"], | ||
directories: true | ||
}) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('when you turn off files and directoies returns empty list', () => { | ||
describe("when you turn off files and directoies returns empty list", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/foo1', 'abc'); | ||
fse.mkdirsSync('a/b/foo2'); | ||
fse.outputFileSync("a/b/foo1", "abc"); | ||
fse.mkdirsSync("a/b/foo2"); | ||
}; | ||
const expectations = (found) => { | ||
const expectations = found => { | ||
expect(found).to.eql([]); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find('a', { | ||
matching: 'foo*', | ||
files: false, | ||
directories: false, | ||
})); | ||
expectations( | ||
jetpack.find("a", { | ||
matching: "foo*", | ||
files: false, | ||
directories: false | ||
}) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a', { | ||
matching: 'foo*', | ||
files: false, | ||
directories: false, | ||
}) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}); | ||
jetpack | ||
.findAsync("a", { | ||
matching: "foo*", | ||
files: false, | ||
directories: false | ||
}) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('can look for symlinks', () => { | ||
describe("can look for symlinks", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file', 'abc'); | ||
fse.mkdirsSync('dir'); | ||
jetpack.symlink('file', 'symfile'); | ||
jetpack.symlink('dir', 'symdir'); | ||
fse.outputFileSync("file", "abc"); | ||
fse.mkdirsSync("dir"); | ||
jetpack.symlink("file", "symfile"); | ||
jetpack.symlink("dir", "symdir"); | ||
}; | ||
const expectations = (found) => { | ||
expect(found).to.eql(['file', 'symdir', 'symfile']); | ||
const expectations = found => { | ||
expect(found).to.eql(["file", "symdir", "symfile"]); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find({ matching: '*', symlinks: true })); | ||
expectations(jetpack.find({ matching: "*", symlinks: true })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync({ matching: '*', symlinks: true }) | ||
.then((found) => { | ||
jetpack.findAsync({ matching: "*", symlinks: true }).then(found => { | ||
expectations(found); | ||
@@ -467,11 +474,13 @@ done(); | ||
describe("throws if path doesn't exist", () => { | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('ENOENT'); | ||
expect(err.message).to.have.string("Path you want to find stuff in doesn't exist"); | ||
const expectations = err => { | ||
expect(err.code).to.equal("ENOENT"); | ||
expect(err.message).to.have.string( | ||
"Path you want to find stuff in doesn't exist" | ||
); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
try { | ||
jetpack.find('a', { matching: '*.txt' }); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.find("a", { matching: "*.txt" }); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -482,5 +491,4 @@ expectations(err); | ||
it('async', (done) => { | ||
jetpack.findAsync('a', { matching: '*.txt' }) | ||
.catch((err) => { | ||
it("async", done => { | ||
jetpack.findAsync("a", { matching: "*.txt" }).catch(err => { | ||
expectations(err); | ||
@@ -492,17 +500,19 @@ done(); | ||
describe('throws if path is a file, not a directory', () => { | ||
describe("throws if path is a file, not a directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b', 'abc'); | ||
fse.outputFileSync("a/b", "abc"); | ||
}; | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('ENOTDIR'); | ||
expect(err.message).to.have.string('Path you want to find stuff in must be a directory'); | ||
const expectations = err => { | ||
expect(err.code).to.equal("ENOTDIR"); | ||
expect(err.message).to.have.string( | ||
"Path you want to find stuff in must be a directory" | ||
); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.find('a/b', { matching: '*.txt' }); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.find("a/b", { matching: "*.txt" }); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -513,6 +523,5 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync('a/b', { matching: '*.txt' }) | ||
.catch((err) => { | ||
jetpack.findAsync("a/b", { matching: "*.txt" }).catch(err => { | ||
expectations(err); | ||
@@ -524,23 +533,22 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c/d.txt', 'abc'); | ||
fse.outputFileSync("a/b/c/d.txt", "abc"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep(['b/c/d.txt']); // NOT a/b/c/d.txt | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep(["b/c/d.txt"]); // NOT a/b/c/d.txt | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
expectations(jetContext.find('b', { matching: '*.txt' })); | ||
expectations(jetContext.find("b", { matching: "*.txt" })); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.findAsync('b', { matching: '*.txt' }) | ||
.then((found) => { | ||
jetContext.findAsync("b", { matching: "*.txt" }).then(found => { | ||
expectations(found); | ||
@@ -552,50 +560,54 @@ done(); | ||
describe('finds dot-dirs and dot-files', () => { | ||
describe("finds dot-dirs and dot-files", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('.dir/file', 'a'); | ||
fse.outputFileSync('.dir/.file', 'b'); | ||
fse.outputFileSync('.foo/.file', 'c'); | ||
fse.outputFileSync(".dir/file", "a"); | ||
fse.outputFileSync(".dir/.file", "b"); | ||
fse.outputFileSync(".foo/.file", "c"); | ||
}; | ||
const expectations = (found) => { | ||
const normalizedPaths = helper.osSep([ | ||
'.dir', | ||
'.dir/.file', | ||
]); | ||
const expectations = found => { | ||
const normalizedPaths = helper.osSep([".dir", ".dir/.file"]); | ||
expect(found).to.eql(normalizedPaths); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.find({ | ||
matching: ['.dir', '.file', '!.foo/**'], | ||
directories: true, | ||
})); | ||
expectations( | ||
jetpack.find({ | ||
matching: [".dir", ".file", "!.foo/**"], | ||
directories: true | ||
}) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.findAsync({ | ||
matching: ['.dir', '.file', '!.foo/**'], | ||
directories: true, | ||
}) | ||
.then((found) => { | ||
expectations(found); | ||
done(); | ||
}); | ||
jetpack | ||
.findAsync({ | ||
matching: [".dir", ".file", "!.foo/**"], | ||
directories: true | ||
}) | ||
.then(found => { | ||
expectations(found); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.find, methodName: 'find' }, | ||
{ type: 'async', method: jetpack.findAsync, methodName: 'findAsync' }, | ||
{ type: "sync", method: jetpack.find, methodName: "find" }, | ||
{ type: "async", method: jetpack.findAsync, methodName: "findAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, {}); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}([path], options) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}([path], options) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -607,7 +619,11 @@ }); | ||
describe('"matching" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method({ matching: 1 }); | ||
}).to.throw(`Argument "options.matching" passed to ${test.methodName}([path], options) must be a string or an array of string. Received number`); | ||
}).to.throw( | ||
`Argument "options.matching" passed to ${ | ||
test.methodName | ||
}([path], options) must be a string or an array of string. Received number` | ||
); | ||
}); | ||
@@ -617,7 +633,11 @@ }); | ||
describe('"files" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { files: 1 }); | ||
}).to.throw(`Argument "options.files" passed to ${test.methodName}([path], options) must be a boolean. Received number`); | ||
test.method("abc", { files: 1 }); | ||
}).to.throw( | ||
`Argument "options.files" passed to ${ | ||
test.methodName | ||
}([path], options) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -627,7 +647,11 @@ }); | ||
describe('"directories" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { directories: 1 }); | ||
}).to.throw(`Argument "options.directories" passed to ${test.methodName}([path], options) must be a boolean. Received number`); | ||
test.method("abc", { directories: 1 }); | ||
}).to.throw( | ||
`Argument "options.directories" passed to ${ | ||
test.methodName | ||
}([path], options) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -637,7 +661,11 @@ }); | ||
describe('"recursive" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { recursive: 1 }); | ||
}).to.throw(`Argument "options.recursive" passed to ${test.methodName}([path], options) must be a boolean. Received number`); | ||
test.method("abc", { recursive: 1 }); | ||
}).to.throw( | ||
`Argument "options.recursive" passed to ${ | ||
test.methodName | ||
}([path], options) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -647,7 +675,11 @@ }); | ||
describe('"symlinks" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { symlinks: 1 }); | ||
}).to.throw(`Argument "options.symlinks" passed to ${test.methodName}([path], options) must be a boolean. Received number`); | ||
test.method("abc", { symlinks: 1 }); | ||
}).to.throw( | ||
`Argument "options.symlinks" passed to ${ | ||
test.methodName | ||
}([path], options) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -654,0 +686,0 @@ }); |
@@ -1,6 +0,6 @@ | ||
'use strict'; | ||
"use strict"; | ||
const os = require('os'); | ||
const crypto = require('crypto'); | ||
const fse = require('fs-extra'); | ||
const os = require("os"); | ||
const crypto = require("crypto"); | ||
const fse = require("fs-extra"); | ||
@@ -10,6 +10,6 @@ const originalCwd = process.cwd(); | ||
process.on('exit', () => { | ||
process.on("exit", () => { | ||
// In case something went wrong and some temp | ||
// directories are still on the disk. | ||
createdDirectories.forEach((path) => { | ||
createdDirectories.forEach(path => { | ||
fse.removeSync(path); | ||
@@ -20,3 +20,3 @@ }); | ||
exports.setCleanTestCwd = () => { | ||
const random = crypto.randomBytes(16).toString('hex'); | ||
const random = crypto.randomBytes(16).toString("hex"); | ||
const path = `${os.tmpdir()}/fs-jetpack-test-${random}`; | ||
@@ -34,3 +34,3 @@ fse.mkdirSync(path); | ||
exports.parseMode = (modeAsNumber) => { | ||
exports.parseMode = modeAsNumber => { | ||
const mode = modeAsNumber.toString(8); | ||
@@ -41,3 +41,3 @@ return mode.substring(mode.length - 3); | ||
// Converts paths to windows or unix formats depending on platform running. | ||
exports.osSep = (path) => { | ||
exports.osSep = path => { | ||
if (Array.isArray(path)) { | ||
@@ -47,6 +47,6 @@ return path.map(exports.osSep); | ||
if (process.platform === 'win32') { | ||
return path.replace(/\//g, '\\'); | ||
if (process.platform === "win32") { | ||
return path.replace(/\//g, "\\"); | ||
} | ||
return path.replace(/\\/g, '/'); | ||
return path.replace(/\\/g, "/"); | ||
}; |
@@ -1,53 +0,53 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('inspectTree', () => { | ||
describe("inspectTree", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('inspects whole tree of files', () => { | ||
describe("inspects whole tree of files", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync('dir/subdir/file.txt', 'defg'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.outputFileSync("dir/subdir/file.txt", "defg"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'dir', | ||
type: 'dir', | ||
name: "dir", | ||
type: "dir", | ||
size: 7, | ||
children: [ | ||
{ | ||
name: 'file.txt', | ||
type: 'file', | ||
size: 3, | ||
}, { | ||
name: 'subdir', | ||
type: 'dir', | ||
name: "file.txt", | ||
type: "file", | ||
size: 3 | ||
}, | ||
{ | ||
name: "subdir", | ||
type: "dir", | ||
size: 4, | ||
children: [ | ||
{ | ||
name: 'file.txt', | ||
type: 'file', | ||
size: 4, | ||
}, | ||
], | ||
}, | ||
], | ||
name: "file.txt", | ||
type: "file", | ||
size: 4 | ||
} | ||
] | ||
} | ||
] | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir')); | ||
expectations(jetpack.inspectTree("dir")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir') | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("dir").then(tree => { | ||
expectations(tree); | ||
@@ -59,11 +59,11 @@ done(); | ||
describe('can calculate size of a whole tree', () => { | ||
describe("can calculate size of a whole tree", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('dir/empty'); | ||
fse.outputFileSync('dir/empty.txt', ''); | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync('dir/subdir/file.txt', 'defg'); | ||
fse.mkdirsSync("dir/empty"); | ||
fse.outputFileSync("dir/empty.txt", ""); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.outputFileSync("dir/subdir/file.txt", "defg"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
// dir | ||
@@ -83,11 +83,10 @@ expect(data.size).to.equal(7); | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir')); | ||
expectations(jetpack.inspectTree("dir")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir') | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("dir").then(tree => { | ||
expectations(tree); | ||
@@ -99,8 +98,8 @@ done(); | ||
describe('can output relative path for every tree node', () => { | ||
describe("can output relative path for every tree node", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/subdir/file.txt', 'defg'); | ||
fse.outputFileSync("dir/subdir/file.txt", "defg"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
// data will look like... | ||
@@ -123,16 +122,17 @@ // { | ||
// } | ||
expect(data.relativePath).to.equal('.'); | ||
expect(data.children[0].relativePath).to.equal('./subdir'); | ||
expect(data.children[0].children[0].relativePath).to.equal('./subdir/file.txt'); | ||
expect(data.relativePath).to.equal("."); | ||
expect(data.children[0].relativePath).to.equal("./subdir"); | ||
expect(data.children[0].children[0].relativePath).to.equal( | ||
"./subdir/file.txt" | ||
); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir', { relativePath: true })); | ||
expectations(jetpack.inspectTree("dir", { relativePath: true })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir', { relativePath: true }) | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("dir", { relativePath: true }).then(tree => { | ||
expectations(tree); | ||
@@ -144,24 +144,23 @@ done(); | ||
describe('if given path is a file just inspects that file', () => { | ||
describe("if given path is a file just inspects that file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'file.txt', | ||
type: 'file', | ||
size: 3, | ||
name: "file.txt", | ||
type: "file", | ||
size: 3 | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir/file.txt')); | ||
expectations(jetpack.inspectTree("dir/file.txt")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir/file.txt') | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("dir/file.txt").then(tree => { | ||
expectations(tree); | ||
@@ -173,25 +172,24 @@ done(); | ||
describe('behaves ok with empty directory', () => { | ||
describe("behaves ok with empty directory", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('empty'); | ||
fse.mkdirsSync("empty"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'empty', | ||
type: 'dir', | ||
name: "empty", | ||
type: "dir", | ||
size: 0, | ||
children: [], | ||
children: [] | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('empty')); | ||
expectations(jetpack.inspectTree("empty")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('empty') | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("empty").then(tree => { | ||
expectations(tree); | ||
@@ -204,13 +202,12 @@ done(); | ||
describe("returns undefined if path doesn't exist", () => { | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.equal(undefined); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.inspectTree('nonexistent')); | ||
it("sync", () => { | ||
expectations(jetpack.inspectTree("nonexistent")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.inspectTreeAsync('nonexistent') | ||
.then((dataAsync) => { | ||
it("async", done => { | ||
jetpack.inspectTreeAsync("nonexistent").then(dataAsync => { | ||
expectations(dataAsync); | ||
@@ -222,22 +219,21 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data.name).to.equal('b.txt'); | ||
const expectations = data => { | ||
expect(data.name).to.equal("b.txt"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
expectations(jetContext.inspectTree('b.txt')); | ||
expectations(jetContext.inspectTree("b.txt")); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.inspectTreeAsync('b.txt') | ||
.then((data) => { | ||
jetContext.inspectTreeAsync("b.txt").then(data => { | ||
expectations(data); | ||
@@ -249,111 +245,118 @@ done(); | ||
describe('reports symlinks by default', () => { | ||
describe("reports symlinks by default", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.symlinkSync('file.txt', 'dir/symlinked_file.txt'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.symlinkSync("file.txt", "dir/symlinked_file.txt"); | ||
}; | ||
const expectations = (tree) => { | ||
const expectations = tree => { | ||
expect(tree).to.eql({ | ||
name: 'dir', | ||
type: 'dir', | ||
name: "dir", | ||
type: "dir", | ||
size: 3, | ||
children: [{ | ||
name: 'file.txt', | ||
type: 'file', | ||
size: 3, | ||
}, { | ||
name: 'symlinked_file.txt', | ||
type: 'symlink', | ||
pointsAt: 'file.txt', | ||
}], | ||
children: [ | ||
{ | ||
name: "file.txt", | ||
type: "file", | ||
size: 3 | ||
}, | ||
{ | ||
name: "symlinked_file.txt", | ||
type: "symlink", | ||
pointsAt: "file.txt" | ||
} | ||
] | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir')); // implicit | ||
expectations(jetpack.inspectTree('dir', { symlinks: 'report' })); // explicit | ||
expectations(jetpack.inspectTree("dir")); // implicit | ||
expectations(jetpack.inspectTree("dir", { symlinks: "report" })); // explicit | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir') // implicit | ||
.then((tree) => { | ||
expectations(tree); | ||
return jetpack.inspectTreeAsync('dir', { symlinks: 'report' }); // explicit | ||
}) | ||
.then((tree) => { | ||
expectations(tree); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.inspectTreeAsync("dir") // implicit | ||
.then(tree => { | ||
expectations(tree); | ||
return jetpack.inspectTreeAsync("dir", { symlinks: "report" }); // explicit | ||
}) | ||
.then(tree => { | ||
expectations(tree); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('follows symlinks when option specified', () => { | ||
describe("follows symlinks when option specified", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.symlinkSync('file.txt', 'dir/symlinked_file.txt'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.symlinkSync("file.txt", "dir/symlinked_file.txt"); | ||
}; | ||
const expectations = (tree) => { | ||
const expectations = tree => { | ||
expect(tree).to.eql({ | ||
name: 'dir', | ||
type: 'dir', | ||
name: "dir", | ||
type: "dir", | ||
size: 6, | ||
children: [{ | ||
name: 'file.txt', | ||
type: 'file', | ||
size: 3, | ||
}, { | ||
name: 'symlinked_file.txt', | ||
type: 'file', | ||
size: 3, | ||
}], | ||
children: [ | ||
{ | ||
name: "file.txt", | ||
type: "file", | ||
size: 3 | ||
}, | ||
{ | ||
name: "symlinked_file.txt", | ||
type: "file", | ||
size: 3 | ||
} | ||
] | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir', { symlinks: 'follow' })); | ||
expectations(jetpack.inspectTree("dir", { symlinks: "follow" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir', { symlinks: 'follow' }) | ||
.then((tree) => { | ||
expectations(tree); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.inspectTreeAsync("dir", { symlinks: "follow" }) | ||
.then(tree => { | ||
expectations(tree); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('can compute checksum of a whole tree', () => { | ||
describe("can compute checksum of a whole tree", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/a.txt', 'abc'); | ||
fse.outputFileSync('dir/b.txt', 'defg'); | ||
fse.outputFileSync("dir/a.txt", "abc"); | ||
fse.outputFileSync("dir/b.txt", "defg"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
// md5 of | ||
// 'a.txt' + '900150983cd24fb0d6963f7d28e17f72' + | ||
// 'b.txt' + '025e4da7edac35ede583f5e8d51aa7ec' | ||
expect(data.md5).to.equal('b0ff9df854172efe752cb36b96c8bccd'); | ||
expect(data.md5).to.equal("b0ff9df854172efe752cb36b96c8bccd"); | ||
// md5 of 'abc' | ||
expect(data.children[0].md5).to.equal('900150983cd24fb0d6963f7d28e17f72'); | ||
expect(data.children[0].md5).to.equal("900150983cd24fb0d6963f7d28e17f72"); | ||
// md5 of 'defg' | ||
expect(data.children[1].md5).to.equal('025e4da7edac35ede583f5e8d51aa7ec'); | ||
expect(data.children[1].md5).to.equal("025e4da7edac35ede583f5e8d51aa7ec"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('dir', { checksum: 'md5' })); | ||
expectations(jetpack.inspectTree("dir", { checksum: "md5" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('dir', { checksum: 'md5' }) | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("dir", { checksum: "md5" }).then(tree => { | ||
expectations(tree); | ||
@@ -365,22 +368,21 @@ done(); | ||
describe('can count checksum of empty directory', () => { | ||
describe("can count checksum of empty directory", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('empty_dir'); | ||
fse.mkdirsSync("empty_dir"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
// md5 of empty string | ||
expect(data.md5).to.equal('d41d8cd98f00b204e9800998ecf8427e'); | ||
expect(data.md5).to.equal("d41d8cd98f00b204e9800998ecf8427e"); | ||
}; | ||
// SYNC | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspectTree('empty_dir', { checksum: 'md5' })); | ||
expectations(jetpack.inspectTree("empty_dir", { checksum: "md5" })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectTreeAsync('empty_dir', { checksum: 'md5' }) | ||
.then((tree) => { | ||
jetpack.inspectTreeAsync("empty_dir", { checksum: "md5" }).then(tree => { | ||
expectations(tree); | ||
@@ -392,14 +394,22 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.inspectTree, methodName: 'inspectTree' }, | ||
{ type: 'async', method: jetpack.inspectTreeAsync, methodName: 'inspectTreeAsync' }, | ||
{ type: "sync", method: jetpack.inspectTree, methodName: "inspectTree" }, | ||
{ | ||
type: "async", | ||
method: jetpack.inspectTreeAsync, | ||
methodName: "inspectTreeAsync" | ||
} | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, [options]) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -411,12 +421,20 @@ }); | ||
describe('"checksum" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { checksum: 1 }); | ||
}).to.throw(`Argument "options.checksum" passed to ${test.methodName}(path, [options]) must be a string. Received number`); | ||
test.method("abc", { checksum: 1 }); | ||
}).to.throw( | ||
`Argument "options.checksum" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a string. Received number` | ||
); | ||
}); | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { checksum: 'foo' }); | ||
}).to.throw(`Argument "options.checksum" passed to ${test.methodName}(path, [options]) must have one of values: md5, sha1, sha256`); | ||
test.method("abc", { checksum: "foo" }); | ||
}).to.throw( | ||
`Argument "options.checksum" passed to ${ | ||
test.methodName | ||
}(path, [options]) must have one of values: md5, sha1, sha256` | ||
); | ||
}); | ||
@@ -426,7 +444,11 @@ }); | ||
describe('"relativePath" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { relativePath: 1 }); | ||
}).to.throw(`Argument "options.relativePath" passed to ${test.methodName}(path, [options]) must be a boolean. Received number`); | ||
test.method("abc", { relativePath: 1 }); | ||
}).to.throw( | ||
`Argument "options.relativePath" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -436,12 +458,20 @@ }); | ||
describe('"symlinks" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { symlinks: 1 }); | ||
}).to.throw(`Argument "options.symlinks" passed to ${test.methodName}(path, [options]) must be a string. Received number`); | ||
test.method("abc", { symlinks: 1 }); | ||
}).to.throw( | ||
`Argument "options.symlinks" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a string. Received number` | ||
); | ||
}); | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { symlinks: 'foo' }); | ||
}).to.throw(`Argument "options.symlinks" passed to ${test.methodName}(path, [options]) must have one of values: report, follow`); | ||
test.method("abc", { symlinks: "foo" }); | ||
}).to.throw( | ||
`Argument "options.symlinks" passed to ${ | ||
test.methodName | ||
}(path, [options]) must have one of values: report, follow` | ||
); | ||
}); | ||
@@ -448,0 +478,0 @@ }); |
@@ -1,34 +0,33 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('inspect', () => { | ||
describe("inspect", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('can inspect a file', () => { | ||
describe("can inspect a file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'file.txt', | ||
type: 'file', | ||
size: 3, | ||
name: "file.txt", | ||
type: "file", | ||
size: 3 | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('dir/file.txt')); | ||
expectations(jetpack.inspect("dir/file.txt")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('dir/file.txt') | ||
.then((data) => { | ||
jetpack.inspectAsync("dir/file.txt").then(data => { | ||
expectations(data); | ||
@@ -40,23 +39,22 @@ done(); | ||
describe('can inspect a directory', () => { | ||
describe("can inspect a directory", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('empty'); | ||
fse.mkdirsSync("empty"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'empty', | ||
type: 'dir', | ||
name: "empty", | ||
type: "dir" | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('empty')); | ||
expectations(jetpack.inspect("empty")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('empty') | ||
.then((data) => { | ||
jetpack.inspectAsync("empty").then(data => { | ||
expectations(data); | ||
@@ -69,13 +67,12 @@ done(); | ||
describe("returns undefined if path doesn't exist", () => { | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.equal(undefined); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.inspect('nonexistent')); | ||
it("sync", () => { | ||
expectations(jetpack.inspect("nonexistent")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.inspectAsync('nonexistent') | ||
.then((data) => { | ||
it("async", done => { | ||
jetpack.inspectAsync("nonexistent").then(data => { | ||
expectations(data); | ||
@@ -87,22 +84,21 @@ done(); | ||
describe('can output file times (ctime, mtime, atime)', () => { | ||
describe("can output file times (ctime, mtime, atime)", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
expect(typeof data.accessTime.getTime).to.equal('function'); | ||
expect(typeof data.modifyTime.getTime).to.equal('function'); | ||
expect(typeof data.changeTime.getTime).to.equal('function'); | ||
const expectations = data => { | ||
expect(typeof data.accessTime.getTime).to.equal("function"); | ||
expect(typeof data.modifyTime.getTime).to.equal("function"); | ||
expect(typeof data.changeTime.getTime).to.equal("function"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('dir/file.txt', { times: true })); | ||
expectations(jetpack.inspect("dir/file.txt", { times: true })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('dir/file.txt', { times: true }) | ||
.then((data) => { | ||
jetpack.inspectAsync("dir/file.txt", { times: true }).then(data => { | ||
expectations(data); | ||
@@ -114,46 +110,46 @@ done(); | ||
describe('can output absolute path', () => { | ||
describe("can output absolute path", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data.absolutePath).to.equal(jetpack.path('dir/file.txt')); | ||
const expectations = data => { | ||
expect(data.absolutePath).to.equal(jetpack.path("dir/file.txt")); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('dir/file.txt', { absolutePath: true })); | ||
expectations(jetpack.inspect("dir/file.txt", { absolutePath: true })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('dir/file.txt', { absolutePath: true }) | ||
.then((data) => { | ||
expectations(data); | ||
done(); | ||
}); | ||
jetpack | ||
.inspectAsync("dir/file.txt", { absolutePath: true }) | ||
.then(data => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data.name).to.equal('b.txt'); | ||
const expectations = data => { | ||
expect(data.name).to.equal("b.txt"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
expectations(jetContext.inspect('b.txt')); | ||
expectations(jetContext.inspect("b.txt")); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.inspectAsync('b.txt') | ||
.then((data) => { | ||
jetContext.inspectAsync("b.txt").then(data => { | ||
expectations(data); | ||
@@ -165,88 +161,95 @@ done(); | ||
describe('reports symlink by default', () => { | ||
describe("reports symlink by default", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.symlinkSync('dir/file.txt', 'symlinked_file.txt'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.symlinkSync("dir/file.txt", "symlinked_file.txt"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'symlinked_file.txt', | ||
type: 'symlink', | ||
pointsAt: helper.osSep('dir/file.txt'), | ||
name: "symlinked_file.txt", | ||
type: "symlink", | ||
pointsAt: helper.osSep("dir/file.txt") | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('symlinked_file.txt')); // implicit | ||
expectations(jetpack.inspect('symlinked_file.txt', { symlinks: 'report' })); // explicit | ||
expectations(jetpack.inspect("symlinked_file.txt")); // implicit | ||
expectations( | ||
jetpack.inspect("symlinked_file.txt", { symlinks: "report" }) | ||
); // explicit | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('symlinked_file.txt') // implicit | ||
.then((data) => { | ||
expectations(data); | ||
return jetpack.inspectAsync('symlinked_file.txt', { symlinks: 'report' }); // explicit | ||
}) | ||
.then((data) => { | ||
expectations(data); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.inspectAsync("symlinked_file.txt") // implicit | ||
.then(data => { | ||
expectations(data); | ||
return jetpack.inspectAsync("symlinked_file.txt", { | ||
symlinks: "report" | ||
}); // explicit | ||
}) | ||
.then(data => { | ||
expectations(data); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
describe('follows symlink if option specified', () => { | ||
describe("follows symlink if option specified", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.symlinkSync('dir/file.txt', 'symlinked_file.txt'); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.symlinkSync("dir/file.txt", "symlinked_file.txt"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql({ | ||
name: 'symlinked_file.txt', | ||
type: 'file', | ||
size: 3, | ||
name: "symlinked_file.txt", | ||
type: "file", | ||
size: 3 | ||
}); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('symlinked_file.txt', { symlinks: 'follow' })); | ||
expectations( | ||
jetpack.inspect("symlinked_file.txt", { symlinks: "follow" }) | ||
); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('symlinked_file.txt', { symlinks: 'follow' }) | ||
.then((data) => { | ||
expectations(data); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.inspectAsync("symlinked_file.txt", { symlinks: "follow" }) | ||
.then(data => { | ||
expectations(data); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
}); | ||
if (process.platform !== 'win32') { | ||
describe('can output file mode (unix only)', () => { | ||
if (process.platform !== "win32") { | ||
describe("can output file mode (unix only)", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('dir/file.txt', 'abc', { | ||
mode: '511', | ||
fse.outputFileSync("dir/file.txt", "abc", { | ||
mode: "511" | ||
}); | ||
}; | ||
const expectations = (data) => { | ||
expect(helper.parseMode(data.mode)).to.equal('511'); | ||
const expectations = data => { | ||
expect(helper.parseMode(data.mode)).to.equal("511"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('dir/file.txt', { mode: true })); | ||
expectations(jetpack.inspect("dir/file.txt", { mode: true })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('dir/file.txt', { mode: true }) | ||
.then((data) => { | ||
jetpack.inspectAsync("dir/file.txt", { mode: true }).then(data => { | ||
expectations(data); | ||
@@ -259,59 +262,62 @@ done(); | ||
describe('checksums', () => { | ||
describe("checksums", () => { | ||
const testsData = [ | ||
{ | ||
name: 'md5', | ||
type: 'md5', | ||
content: 'abc', | ||
expected: '900150983cd24fb0d6963f7d28e17f72', | ||
name: "md5", | ||
type: "md5", | ||
content: "abc", | ||
expected: "900150983cd24fb0d6963f7d28e17f72" | ||
}, | ||
{ | ||
name: 'sha1', | ||
type: 'sha1', | ||
content: 'abc', | ||
expected: 'a9993e364706816aba3e25717850c26c9cd0d89d', | ||
name: "sha1", | ||
type: "sha1", | ||
content: "abc", | ||
expected: "a9993e364706816aba3e25717850c26c9cd0d89d" | ||
}, | ||
{ | ||
name: 'sha256', | ||
type: 'sha256', | ||
content: 'abc', | ||
expected: 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', | ||
name: "sha256", | ||
type: "sha256", | ||
content: "abc", | ||
expected: | ||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" | ||
}, | ||
{ | ||
name: 'sha512', | ||
type: 'sha512', | ||
content: 'abc', | ||
expected: 'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f', | ||
name: "sha512", | ||
type: "sha512", | ||
content: "abc", | ||
expected: | ||
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" | ||
}, | ||
{ | ||
name: 'calculates correctly checksum of an empty file', | ||
type: 'md5', | ||
content: '', | ||
expected: 'd41d8cd98f00b204e9800998ecf8427e', | ||
}, | ||
name: "calculates correctly checksum of an empty file", | ||
type: "md5", | ||
content: "", | ||
expected: "d41d8cd98f00b204e9800998ecf8427e" | ||
} | ||
]; | ||
testsData.forEach((test) => { | ||
testsData.forEach(test => { | ||
describe(test.name, () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', test.content); | ||
fse.outputFileSync("file.txt", test.content); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data[test.type]).to.eql(test.expected); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.inspect('file.txt', { checksum: test.type })); | ||
expectations(jetpack.inspect("file.txt", { checksum: test.type })); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.inspectAsync('file.txt', { checksum: test.type }) | ||
.then((data) => { | ||
expectations(data); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.inspectAsync("file.txt", { checksum: test.type }) | ||
.then(data => { | ||
expectations(data); | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
@@ -322,14 +328,22 @@ }); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.inspect, methodName: 'inspect' }, | ||
{ type: 'async', method: jetpack.inspectAsync, methodName: 'inspectAsync' }, | ||
{ type: "sync", method: jetpack.inspect, methodName: "inspect" }, | ||
{ | ||
type: "async", | ||
method: jetpack.inspectAsync, | ||
methodName: "inspectAsync" | ||
} | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, [options]) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -341,12 +355,20 @@ }); | ||
describe('"checksum" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { checksum: 1 }); | ||
}).to.throw(`Argument "options.checksum" passed to ${test.methodName}(path, [options]) must be a string. Received number`); | ||
test.method("abc", { checksum: 1 }); | ||
}).to.throw( | ||
`Argument "options.checksum" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a string. Received number` | ||
); | ||
}); | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { checksum: 'foo' }); | ||
}).to.throw(`Argument "options.checksum" passed to ${test.methodName}(path, [options]) must have one of values: md5, sha1, sha256`); | ||
test.method("abc", { checksum: "foo" }); | ||
}).to.throw( | ||
`Argument "options.checksum" passed to ${ | ||
test.methodName | ||
}(path, [options]) must have one of values: md5, sha1, sha256` | ||
); | ||
}); | ||
@@ -356,7 +378,11 @@ }); | ||
describe('"mode" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { mode: 1 }); | ||
}).to.throw(`Argument "options.mode" passed to ${test.methodName}(path, [options]) must be a boolean. Received number`); | ||
test.method("abc", { mode: 1 }); | ||
}).to.throw( | ||
`Argument "options.mode" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -366,7 +392,11 @@ }); | ||
describe('"times" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { times: 1 }); | ||
}).to.throw(`Argument "options.times" passed to ${test.methodName}(path, [options]) must be a boolean. Received number`); | ||
test.method("abc", { times: 1 }); | ||
}).to.throw( | ||
`Argument "options.times" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -376,7 +406,11 @@ }); | ||
describe('"absolutePath" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { absolutePath: 1 }); | ||
}).to.throw(`Argument "options.absolutePath" passed to ${test.methodName}(path, [options]) must be a boolean. Received number`); | ||
test.method("abc", { absolutePath: 1 }); | ||
}).to.throw( | ||
`Argument "options.absolutePath" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -386,12 +420,20 @@ }); | ||
describe('"symlinks" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { symlinks: 1 }); | ||
}).to.throw(`Argument "options.symlinks" passed to ${test.methodName}(path, [options]) must be a string. Received number`); | ||
test.method("abc", { symlinks: 1 }); | ||
}).to.throw( | ||
`Argument "options.symlinks" passed to ${ | ||
test.methodName | ||
}(path, [options]) must be a string. Received number` | ||
); | ||
}); | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', { symlinks: 'foo' }); | ||
}).to.throw(`Argument "options.symlinks" passed to ${test.methodName}(path, [options]) must have one of values: report, follow`); | ||
test.method("abc", { symlinks: "foo" }); | ||
}).to.throw( | ||
`Argument "options.symlinks" passed to ${ | ||
test.methodName | ||
}(path, [options]) must have one of values: report, follow` | ||
); | ||
}); | ||
@@ -398,0 +440,0 @@ }); |
@@ -1,33 +0,32 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('list', () => { | ||
describe("list", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('lists file names in given path', () => { | ||
describe("lists file names in given path", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('dir/empty'); | ||
fse.outputFileSync('dir/empty.txt', ''); | ||
fse.outputFileSync('dir/file.txt', 'abc'); | ||
fse.outputFileSync('dir/subdir/file.txt', 'defg'); | ||
fse.mkdirsSync("dir/empty"); | ||
fse.outputFileSync("dir/empty.txt", ""); | ||
fse.outputFileSync("dir/file.txt", "abc"); | ||
fse.outputFileSync("dir/subdir/file.txt", "defg"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data).to.eql(['empty', 'empty.txt', 'file.txt', 'subdir']); | ||
const expectations = data => { | ||
expect(data).to.eql(["empty", "empty.txt", "file.txt", "subdir"]); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.list('dir')); | ||
expectations(jetpack.list("dir")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.listAsync('dir') | ||
.then((listAsync) => { | ||
jetpack.listAsync("dir").then(listAsync => { | ||
expectations(listAsync); | ||
@@ -39,14 +38,14 @@ done(); | ||
describe('lists CWD if no path parameter passed', () => { | ||
describe("lists CWD if no path parameter passed", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('dir/a'); | ||
fse.outputFileSync('dir/b'); | ||
fse.mkdirsSync("dir/a"); | ||
fse.outputFileSync("dir/b"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data).to.eql(['a', 'b']); | ||
const expectations = data => { | ||
expect(data).to.eql(["a", "b"]); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('dir'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("dir"); | ||
preparations(); | ||
@@ -56,7 +55,6 @@ expectations(jetContext.list()); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('dir'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("dir"); | ||
preparations(); | ||
jetContext.listAsync() | ||
.then((list) => { | ||
jetContext.listAsync().then(list => { | ||
expectations(list); | ||
@@ -69,13 +67,12 @@ done(); | ||
describe("returns undefined if path doesn't exist", () => { | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.equal(undefined); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.list('nonexistent')); | ||
it("sync", () => { | ||
expectations(jetpack.list("nonexistent")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.listAsync('nonexistent') | ||
.then((data) => { | ||
it("async", done => { | ||
jetpack.listAsync("nonexistent").then(data => { | ||
expectations(data); | ||
@@ -87,16 +84,16 @@ done(); | ||
describe('throws if given path is not a directory', () => { | ||
describe("throws if given path is not a directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', 'abc'); | ||
fse.outputFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('ENOTDIR'); | ||
const expectations = err => { | ||
expect(err.code).to.equal("ENOTDIR"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.list('file.txt'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.list("file.txt"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -107,6 +104,5 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.listAsync('file.txt') | ||
.catch((err) => { | ||
jetpack.listAsync("file.txt").catch(err => { | ||
expectations(err); | ||
@@ -118,22 +114,21 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.outputFileSync("a/b/c.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data).to.eql(['c.txt']); | ||
const expectations = data => { | ||
expect(data).to.eql(["c.txt"]); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
expectations(jetContext.list('b')); | ||
expectations(jetContext.list("b")); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.listAsync('b') | ||
.then((data) => { | ||
jetContext.listAsync("b").then(data => { | ||
expectations(data); | ||
@@ -145,14 +140,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.list, methodName: 'list' }, | ||
{ type: 'async', method: jetpack.listAsync, methodName: 'listAsync' }, | ||
{ type: "sync", method: jetpack.list, methodName: "list" }, | ||
{ type: "async", method: jetpack.listAsync, methodName: "listAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(true); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path) must be a string or an undefined. Received boolean`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path) must be a string or an undefined. Received boolean` | ||
); | ||
}); | ||
@@ -159,0 +158,0 @@ }); |
/* eslint no-console:0 */ | ||
'use strict'; | ||
"use strict"; | ||
const util = require('util'); | ||
const expect = require('chai').expect; | ||
const jetpack = require('..'); | ||
const util = require("util"); | ||
const expect = require("chai").expect; | ||
const jetpack = require(".."); | ||
@@ -13,4 +13,4 @@ if (util.inspect.custom !== undefined) { | ||
// introduced in node v6.6.0, hence this test is runned conditionally. | ||
describe('console.log', () => { | ||
it('can be printed by console.log', () => { | ||
describe("console.log", () => { | ||
it("can be printed by console.log", () => { | ||
expect(() => { | ||
@@ -17,0 +17,0 @@ console.log(jetpack); |
@@ -1,33 +0,32 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('move', () => { | ||
describe("move", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('moves file', () => { | ||
describe("moves file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b.txt').shouldNotExist(); | ||
path('c.txt').shouldBeFileWithContent('abc'); | ||
path("a/b.txt").shouldNotExist(); | ||
path("c.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.move('a/b.txt', 'c.txt'); | ||
jetpack.move("a/b.txt", "c.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.moveAsync('a/b.txt', 'c.txt') | ||
.then(() => { | ||
jetpack.moveAsync("a/b.txt", "c.txt").then(() => { | ||
expectations(); | ||
@@ -39,23 +38,22 @@ done(); | ||
describe('moves directory', () => { | ||
describe("moves directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.mkdirsSync('x'); | ||
fse.outputFileSync("a/b/c.txt", "abc"); | ||
fse.mkdirsSync("x"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldNotExist(); | ||
path('x/y/b/c.txt').shouldBeFileWithContent('abc'); | ||
path("a").shouldNotExist(); | ||
path("x/y/b/c.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.move('a', 'x/y'); | ||
jetpack.move("a", "x/y"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.moveAsync('a', 'x/y') | ||
.then(() => { | ||
jetpack.moveAsync("a", "x/y").then(() => { | ||
expectations(); | ||
@@ -67,22 +65,21 @@ done(); | ||
describe('creates nonexistent directories for destination path', () => { | ||
describe("creates nonexistent directories for destination path", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a.txt', 'abc'); | ||
fse.outputFileSync("a.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a.txt').shouldNotExist(); | ||
path('a/b/z.txt').shouldBeFileWithContent('abc'); | ||
path("a.txt").shouldNotExist(); | ||
path("a/b/z.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.move('a.txt', 'a/b/z.txt'); | ||
jetpack.move("a.txt", "a/b/z.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.moveAsync('a.txt', 'a/b/z.txt') | ||
.then(() => { | ||
jetpack.moveAsync("a.txt", "a/b/z.txt").then(() => { | ||
expectations(); | ||
@@ -95,11 +92,11 @@ done(); | ||
describe("generates nice error when source path doesn't exist", () => { | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('ENOENT'); | ||
const expectations = err => { | ||
expect(err.code).to.equal("ENOENT"); | ||
expect(err.message).to.have.string("Path to move doesn't exist"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
try { | ||
jetpack.move('a', 'b'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.move("a", "b"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -110,5 +107,4 @@ expectations(err); | ||
it('async', (done) => { | ||
jetpack.moveAsync('a', 'b') | ||
.catch((err) => { | ||
it("async", done => { | ||
jetpack.moveAsync("a", "b").catch(err => { | ||
expectations(err); | ||
@@ -120,24 +116,23 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b.txt').shouldNotExist(); | ||
path('a/x.txt').shouldBeFileWithContent('abc'); | ||
path("a/b.txt").shouldNotExist(); | ||
path("a/x.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.move('b.txt', 'x.txt'); | ||
jetContext.move("b.txt", "x.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.moveAsync('b.txt', 'x.txt') | ||
.then(() => { | ||
jetContext.moveAsync("b.txt", "x.txt").then(() => { | ||
expectations(); | ||
@@ -149,14 +144,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.move, methodName: 'move' }, | ||
{ type: 'async', method: jetpack.moveAsync, methodName: 'moveAsync' }, | ||
{ type: "sync", method: jetpack.move, methodName: "move" }, | ||
{ type: "async", method: jetpack.moveAsync, methodName: "moveAsync" } | ||
]; | ||
describe('"from" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, 'xyz'); | ||
}).to.throw(`Argument "from" passed to ${test.methodName}(from, to) must be a string. Received undefined`); | ||
test.method(undefined, "xyz"); | ||
}).to.throw( | ||
`Argument "from" passed to ${ | ||
test.methodName | ||
}(from, to) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -167,7 +166,11 @@ }); | ||
describe('"to" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', undefined); | ||
}).to.throw(`Argument "to" passed to ${test.methodName}(from, to) must be a string. Received undefined`); | ||
test.method("abc", undefined); | ||
}).to.throw( | ||
`Argument "to" passed to ${ | ||
test.methodName | ||
}(from, to) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -174,0 +177,0 @@ }); |
@@ -1,31 +0,31 @@ | ||
'use strict'; | ||
"use strict"; | ||
const pathUtil = require('path'); | ||
const expect = require('chai').expect; | ||
const jetpack = require('..'); | ||
const pathUtil = require("path"); | ||
const expect = require("chai").expect; | ||
const jetpack = require(".."); | ||
describe('path', () => { | ||
it('if no parameters passed returns same path as cwd()', () => { | ||
describe("path", () => { | ||
it("if no parameters passed returns same path as cwd()", () => { | ||
expect(jetpack.path()).to.equal(jetpack.cwd()); | ||
expect(jetpack.path('')).to.equal(jetpack.cwd()); | ||
expect(jetpack.path('.')).to.equal(jetpack.cwd()); | ||
expect(jetpack.path("")).to.equal(jetpack.cwd()); | ||
expect(jetpack.path(".")).to.equal(jetpack.cwd()); | ||
}); | ||
it('is absolute if prepending slash present', () => { | ||
expect(jetpack.path('/blah')).to.equal(pathUtil.resolve('/blah')); | ||
it("is absolute if prepending slash present", () => { | ||
expect(jetpack.path("/blah")).to.equal(pathUtil.resolve("/blah")); | ||
}); | ||
it('resolves to CWD path of this jetpack instance', () => { | ||
const a = pathUtil.join(jetpack.cwd(), 'a'); | ||
it("resolves to CWD path of this jetpack instance", () => { | ||
const a = pathUtil.join(jetpack.cwd(), "a"); | ||
// Create jetpack instance with other CWD | ||
const jetpackSubdir = jetpack.cwd('subdir'); | ||
const b = pathUtil.join(jetpack.cwd(), 'subdir', 'b'); | ||
expect(jetpack.path('a')).to.equal(a); | ||
expect(jetpackSubdir.path('b')).to.equal(b); | ||
const jetpackSubdir = jetpack.cwd("subdir"); | ||
const b = pathUtil.join(jetpack.cwd(), "subdir", "b"); | ||
expect(jetpack.path("a")).to.equal(a); | ||
expect(jetpackSubdir.path("b")).to.equal(b); | ||
}); | ||
it('can take unlimited number of arguments as path parts', () => { | ||
const abc = pathUtil.join(jetpack.cwd(), 'a', 'b', 'c'); | ||
expect(jetpack.path('a', 'b', 'c')).to.equal(abc); | ||
it("can take unlimited number of arguments as path parts", () => { | ||
const abc = pathUtil.join(jetpack.cwd(), "a", "b", "c"); | ||
expect(jetpack.path("a", "b", "c")).to.equal(abc); | ||
}); | ||
}); |
@@ -1,47 +0,48 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('read', () => { | ||
describe("read", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('reads file as a string', () => { | ||
describe("reads file as a string", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', 'abc'); | ||
fse.outputFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = (content) => { | ||
expect(content).to.equal('abc'); | ||
const expectations = content => { | ||
expect(content).to.equal("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.read('file.txt')); // defaults to 'utf8' | ||
expectations(jetpack.read('file.txt', 'utf8')); // explicitly specified | ||
expectations(jetpack.read("file.txt")); // defaults to 'utf8' | ||
expectations(jetpack.read("file.txt", "utf8")); // explicitly specified | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.readAsync('file.txt') // defaults to 'utf8' | ||
.then((content) => { | ||
expectations(content); | ||
return jetpack.readAsync('file.txt', 'utf8'); // explicitly said | ||
}) | ||
.then((content) => { | ||
expectations(content); | ||
done(); | ||
}); | ||
jetpack | ||
.readAsync("file.txt") // defaults to 'utf8' | ||
.then(content => { | ||
expectations(content); | ||
return jetpack.readAsync("file.txt", "utf8"); // explicitly said | ||
}) | ||
.then(content => { | ||
expectations(content); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('reads file as a Buffer', () => { | ||
describe("reads file as a Buffer", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', new Buffer([11, 22])); | ||
fse.outputFileSync("file.txt", new Buffer([11, 22])); | ||
}; | ||
const expectations = (content) => { | ||
const expectations = content => { | ||
expect(Buffer.isBuffer(content)).to.equal(true); | ||
@@ -53,11 +54,10 @@ expect(content.length).to.equal(2); | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.read('file.txt', 'buffer')); | ||
expectations(jetpack.read("file.txt", "buffer")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.readAsync('file.txt', 'buffer') | ||
.then((content) => { | ||
jetpack.readAsync("file.txt", "buffer").then(content => { | ||
expectations(content); | ||
@@ -69,24 +69,23 @@ done(); | ||
describe('reads file as JSON', () => { | ||
describe("reads file as JSON", () => { | ||
const obj = { | ||
utf8: 'ąćłźż', | ||
utf8: "ąćłźż" | ||
}; | ||
const preparations = () => { | ||
fse.outputFileSync('file.json', JSON.stringify(obj)); | ||
fse.outputFileSync("file.json", JSON.stringify(obj)); | ||
}; | ||
const expectations = (content) => { | ||
const expectations = content => { | ||
expect(content).to.eql(obj); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.read('file.json', 'json')); | ||
expectations(jetpack.read("file.json", "json")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.readAsync('file.json', 'json') | ||
.then((content) => { | ||
jetpack.readAsync("file.json", "json").then(content => { | ||
expectations(content); | ||
@@ -98,16 +97,16 @@ done(); | ||
describe('gives nice error message when JSON parsing failed', () => { | ||
describe("gives nice error message when JSON parsing failed", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.json', '{ "abc: 123 }'); // Malformed JSON | ||
fse.outputFileSync("file.json", '{ "abc: 123 }'); // Malformed JSON | ||
}; | ||
const expectations = (err) => { | ||
expect(err.message).to.have.string('JSON parsing failed while reading'); | ||
const expectations = err => { | ||
expect(err.message).to.have.string("JSON parsing failed while reading"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.read('file.json', 'json'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.read("file.json", "json"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -118,6 +117,5 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.readAsync('file.json', 'json') | ||
.catch((err) => { | ||
jetpack.readAsync("file.json", "json").catch(err => { | ||
expectations(err); | ||
@@ -129,25 +127,24 @@ done(); | ||
describe('reads file as JSON with Date parsing', () => { | ||
describe("reads file as JSON with Date parsing", () => { | ||
const obj = { | ||
utf8: 'ąćłźż', | ||
date: new Date(), | ||
utf8: "ąćłźż", | ||
date: new Date() | ||
}; | ||
const preparations = () => { | ||
fse.outputFileSync('file.json', JSON.stringify(obj)); | ||
fse.outputFileSync("file.json", JSON.stringify(obj)); | ||
}; | ||
const expectations = (content) => { | ||
const expectations = content => { | ||
expect(content).to.eql(obj); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
expectations(jetpack.read('file.json', 'jsonWithDates')); | ||
expectations(jetpack.read("file.json", "jsonWithDates")); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.readAsync('file.json', 'jsonWithDates') | ||
.then((content) => { | ||
jetpack.readAsync("file.json", "jsonWithDates").then(content => { | ||
expectations(content); | ||
@@ -160,43 +157,44 @@ done(); | ||
describe("returns undefined if file doesn't exist", () => { | ||
const expectations = (content) => { | ||
const expectations = content => { | ||
expect(content).to.equal(undefined); | ||
}; | ||
it('sync', () => { | ||
expectations(jetpack.read('nonexistent.txt')); | ||
expectations(jetpack.read('nonexistent.txt', 'json')); | ||
expectations(jetpack.read('nonexistent.txt', 'buffer')); | ||
it("sync", () => { | ||
expectations(jetpack.read("nonexistent.txt")); | ||
expectations(jetpack.read("nonexistent.txt", "json")); | ||
expectations(jetpack.read("nonexistent.txt", "buffer")); | ||
}); | ||
it('async', (done) => { | ||
jetpack.readAsync('nonexistent.txt') | ||
.then((content) => { | ||
expectations(content); | ||
return jetpack.readAsync('nonexistent.txt', 'json'); | ||
}) | ||
.then((content) => { | ||
expectations(content); | ||
return jetpack.readAsync('nonexistent.txt', 'buffer'); | ||
}) | ||
.then((content) => { | ||
expectations(content); | ||
done(); | ||
}); | ||
it("async", done => { | ||
jetpack | ||
.readAsync("nonexistent.txt") | ||
.then(content => { | ||
expectations(content); | ||
return jetpack.readAsync("nonexistent.txt", "json"); | ||
}) | ||
.then(content => { | ||
expectations(content); | ||
return jetpack.readAsync("nonexistent.txt", "buffer"); | ||
}) | ||
.then(content => { | ||
expectations(content); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('throws if given path is a directory', () => { | ||
describe("throws if given path is a directory", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('dir'); | ||
fse.mkdirsSync("dir"); | ||
}; | ||
const expectations = (err) => { | ||
expect(err.code).to.equal('EISDIR'); | ||
const expectations = err => { | ||
expect(err.code).to.equal("EISDIR"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
try { | ||
jetpack.read('dir'); | ||
throw new Error('Expected error to be thrown'); | ||
jetpack.read("dir"); | ||
throw new Error("Expected error to be thrown"); | ||
} catch (err) { | ||
@@ -207,6 +205,5 @@ expectations(err); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.readAsync('dir') | ||
.catch((err) => { | ||
jetpack.readAsync("dir").catch(err => { | ||
expectations(err); | ||
@@ -218,22 +215,21 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/file.txt', 'abc'); | ||
fse.outputFileSync("a/file.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
expect(data).to.equal('abc'); | ||
const expectations = data => { | ||
expect(data).to.equal("abc"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
expectations(jetContext.read('file.txt')); | ||
expectations(jetContext.read("file.txt")); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.readAsync('file.txt') | ||
.then((data) => { | ||
jetContext.readAsync("file.txt").then(data => { | ||
expectations(data); | ||
@@ -245,14 +241,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.read, methodName: 'read' }, | ||
{ type: 'async', method: jetpack.readAsync, methodName: 'readAsync' }, | ||
{ type: "sync", method: jetpack.read, methodName: "read" }, | ||
{ type: "async", method: jetpack.readAsync, methodName: "readAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, 'xyz'); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, returnAs) must be a string. Received undefined`); | ||
test.method(undefined, "xyz"); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, returnAs) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -263,10 +263,18 @@ }); | ||
describe('"returnAs" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', true); | ||
}).to.throw(`Argument "returnAs" passed to ${test.methodName}(path, returnAs) must be a string or an undefined. Received boolean`); | ||
test.method("abc", true); | ||
}).to.throw( | ||
`Argument "returnAs" passed to ${ | ||
test.methodName | ||
}(path, returnAs) must be a string or an undefined. Received boolean` | ||
); | ||
expect(() => { | ||
test.method('abc', 'foo'); | ||
}).to.throw(`Argument "returnAs" passed to ${test.methodName}(path, returnAs) must have one of values: utf8, buffer, json, jsonWithDates`); | ||
test.method("abc", "foo"); | ||
}).to.throw( | ||
`Argument "returnAs" passed to ${ | ||
test.methodName | ||
}(path, returnAs) must have one of values: utf8, buffer, json, jsonWithDates` | ||
); | ||
}); | ||
@@ -273,0 +281,0 @@ }); |
@@ -1,10 +0,10 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('remove', () => { | ||
describe("remove", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
@@ -14,9 +14,8 @@ afterEach(helper.switchBackToCorrectCwd); | ||
describe("doesn't throw if path already doesn't exist", () => { | ||
it('sync', () => { | ||
jetpack.remove('dir'); | ||
it("sync", () => { | ||
jetpack.remove("dir"); | ||
}); | ||
it('async', (done) => { | ||
jetpack.removeAsync('dir') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.removeAsync("dir").then(() => { | ||
done(); | ||
@@ -27,21 +26,20 @@ }); | ||
describe('should delete file', () => { | ||
describe("should delete file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('file.txt', 'abc'); | ||
fse.outputFileSync("file.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('file.txt').shouldNotExist(); | ||
path("file.txt").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.remove('file.txt'); | ||
jetpack.remove("file.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.removeAsync('file.txt') | ||
.then(() => { | ||
jetpack.removeAsync("file.txt").then(() => { | ||
expectations(); | ||
@@ -53,23 +51,22 @@ done(); | ||
describe('removes directory with stuff inside', () => { | ||
describe("removes directory with stuff inside", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('a/b/c'); | ||
fse.outputFileSync('a/f.txt', 'abc'); | ||
fse.outputFileSync('a/b/f.txt', '123'); | ||
fse.mkdirsSync("a/b/c"); | ||
fse.outputFileSync("a/f.txt", "abc"); | ||
fse.outputFileSync("a/b/f.txt", "123"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldNotExist(); | ||
path("a").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.remove('a'); | ||
jetpack.remove("a"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.removeAsync('a') | ||
.then(() => { | ||
jetpack.removeAsync("a").then(() => { | ||
expectations(); | ||
@@ -81,17 +78,17 @@ done(); | ||
describe('will retry attempt if file is locked', () => { | ||
describe("will retry attempt if file is locked", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('a/b/c'); | ||
fse.outputFileSync('a/f.txt', 'abc'); | ||
fse.outputFileSync('a/b/f.txt', '123'); | ||
fse.mkdirsSync("a/b/c"); | ||
fse.outputFileSync("a/f.txt", "abc"); | ||
fse.outputFileSync("a/b/f.txt", "123"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldNotExist(); | ||
path("a").shouldNotExist(); | ||
}; | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
fse.open('a/f.txt', 'w', (err, fd) => { | ||
fse.open("a/f.txt", "w", (err, fd) => { | ||
if (err) { | ||
@@ -105,8 +102,9 @@ done(err); | ||
jetpack.removeAsync('a') | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
jetpack | ||
.removeAsync("a") | ||
.then(() => { | ||
expectations(); | ||
done(); | ||
}) | ||
.catch(done); | ||
} | ||
@@ -117,24 +115,23 @@ }); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', '123'); | ||
fse.outputFileSync("a/b/c.txt", "123"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldBeDirectory(); | ||
path('a/b').shouldNotExist(); | ||
path("a").shouldBeDirectory(); | ||
path("a/b").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.remove('b'); | ||
jetContext.remove("b"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.removeAsync('b') | ||
.then(() => { | ||
jetContext.removeAsync("b").then(() => { | ||
expectations(); | ||
@@ -146,13 +143,13 @@ done(); | ||
describe('can be called with no parameters, what will remove CWD directory', () => { | ||
describe("can be called with no parameters, what will remove CWD directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.outputFileSync("a/b/c.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a').shouldNotExist(); | ||
path("a").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
@@ -163,7 +160,6 @@ jetContext.remove(); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.removeAsync() | ||
.then(() => { | ||
jetContext.removeAsync().then(() => { | ||
expectations(); | ||
@@ -175,26 +171,25 @@ done(); | ||
describe('removes only symlinks, never real content where symlinks point', () => { | ||
describe("removes only symlinks, never real content where symlinks point", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('have_to_stay_file', 'abc'); | ||
fse.mkdirsSync('to_remove'); | ||
fse.symlinkSync('../have_to_stay_file', 'to_remove/symlink'); | ||
fse.outputFileSync("have_to_stay_file", "abc"); | ||
fse.mkdirsSync("to_remove"); | ||
fse.symlinkSync("../have_to_stay_file", "to_remove/symlink"); | ||
// Make sure we symlinked it properly. | ||
expect(fse.readFileSync('to_remove/symlink', 'utf8')).to.equal('abc'); | ||
expect(fse.readFileSync("to_remove/symlink", "utf8")).to.equal("abc"); | ||
}; | ||
const expectations = () => { | ||
path('have_to_stay_file').shouldBeFileWithContent('abc'); | ||
path('to_remove').shouldNotExist(); | ||
path("have_to_stay_file").shouldBeFileWithContent("abc"); | ||
path("to_remove").shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.remove('to_remove'); | ||
jetpack.remove("to_remove"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.removeAsync('to_remove') | ||
.then(() => { | ||
jetpack.removeAsync("to_remove").then(() => { | ||
expectations(); | ||
@@ -206,14 +201,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.remove, methodName: 'remove' }, | ||
{ type: 'async', method: jetpack.removeAsync, methodName: 'removeAsync' }, | ||
{ type: "sync", method: jetpack.remove, methodName: "remove" }, | ||
{ type: "async", method: jetpack.removeAsync, methodName: "removeAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(true); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}([path]) must be a string or an undefined. Received boolean`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}([path]) must be a string or an undefined. Received boolean` | ||
); | ||
}); | ||
@@ -220,0 +219,0 @@ }); |
@@ -1,33 +0,32 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('rename', () => { | ||
describe("rename", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('renames file', () => { | ||
describe("renames file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b.txt', 'abc'); | ||
fse.outputFileSync("a/b.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b.txt').shouldNotExist(); | ||
path('a/x.txt').shouldBeFileWithContent('abc'); | ||
path("a/b.txt").shouldNotExist(); | ||
path("a/x.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.rename('a/b.txt', 'x.txt'); | ||
jetpack.rename("a/b.txt", "x.txt"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.renameAsync('a/b.txt', 'x.txt') | ||
.then(() => { | ||
jetpack.renameAsync("a/b.txt", "x.txt").then(() => { | ||
expectations(); | ||
@@ -39,22 +38,21 @@ done(); | ||
describe('renames directory', () => { | ||
describe("renames directory", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.outputFileSync("a/b/c.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b').shouldNotExist(); | ||
path('a/x').shouldBeDirectory(); | ||
path("a/b").shouldNotExist(); | ||
path("a/x").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.rename('a/b', 'x'); | ||
jetpack.rename("a/b", "x"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.renameAsync('a/b', 'x') | ||
.then(() => { | ||
jetpack.renameAsync("a/b", "x").then(() => { | ||
expectations(); | ||
@@ -66,24 +64,23 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/c.txt', 'abc'); | ||
fse.outputFileSync("a/b/c.txt", "abc"); | ||
}; | ||
const expectations = () => { | ||
path('a/b').shouldNotExist(); | ||
path('a/x').shouldBeDirectory(); | ||
path("a/b").shouldNotExist(); | ||
path("a/x").shouldBeDirectory(); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.rename('b', 'x'); | ||
jetContext.rename("b", "x"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
preparations(); | ||
jetContext.renameAsync('b', 'x') | ||
.then(() => { | ||
jetContext.renameAsync("b", "x").then(() => { | ||
expectations(); | ||
@@ -95,14 +92,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.rename, methodName: 'rename' }, | ||
{ type: 'async', method: jetpack.renameAsync, methodName: 'renameAsync' }, | ||
{ type: "sync", method: jetpack.rename, methodName: "rename" }, | ||
{ type: "async", method: jetpack.renameAsync, methodName: "renameAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, 'xyz'); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, newName) must be a string. Received undefined`); | ||
test.method(undefined, "xyz"); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, newName) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -113,7 +114,11 @@ }); | ||
describe('"newName" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', undefined); | ||
}).to.throw(`Argument "newName" passed to ${test.methodName}(path, newName) must be a string. Received undefined`); | ||
test.method("abc", undefined); | ||
}).to.throw( | ||
`Argument "newName" passed to ${ | ||
test.methodName | ||
}(path, newName) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -120,0 +125,0 @@ }); |
@@ -1,19 +0,19 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('streams', () => { | ||
describe("streams", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
it('exposes vanilla stream methods', (done) => { | ||
fse.outputFileSync('a.txt', 'abc'); | ||
it("exposes vanilla stream methods", done => { | ||
fse.outputFileSync("a.txt", "abc"); | ||
const input = jetpack.createReadStream('a.txt'); | ||
const output = jetpack.createWriteStream('b.txt'); | ||
output.on('finish', () => { | ||
path('b.txt').shouldBeFileWithContent('abc'); | ||
const input = jetpack.createReadStream("a.txt"); | ||
const output = jetpack.createWriteStream("b.txt"); | ||
output.on("finish", () => { | ||
path("b.txt").shouldBeFileWithContent("abc"); | ||
done(); | ||
@@ -24,11 +24,11 @@ }); | ||
it('stream methods respect jetpack internal CWD', (done) => { | ||
const dir = jetpack.cwd('dir'); | ||
it("stream methods respect jetpack internal CWD", done => { | ||
const dir = jetpack.cwd("dir"); | ||
fse.outputFileSync('dir/a.txt', 'abc'); | ||
fse.outputFileSync("dir/a.txt", "abc"); | ||
const input = dir.createReadStream('a.txt'); | ||
const output = dir.createWriteStream('b.txt'); | ||
output.on('finish', () => { | ||
path('dir/b.txt').shouldBeFileWithContent('abc'); | ||
const input = dir.createReadStream("a.txt"); | ||
const output = dir.createWriteStream("b.txt"); | ||
output.on("finish", () => { | ||
path("dir/b.txt").shouldBeFileWithContent("abc"); | ||
done(); | ||
@@ -35,0 +35,0 @@ }); |
@@ -1,26 +0,25 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('symlink', () => { | ||
describe("symlink", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('can create a symlink', () => { | ||
describe("can create a symlink", () => { | ||
const expectations = () => { | ||
expect(fse.lstatSync('symlink').isSymbolicLink()).to.equal(true); | ||
expect(fse.readlinkSync('symlink')).to.equal('some_path'); | ||
expect(fse.lstatSync("symlink").isSymbolicLink()).to.equal(true); | ||
expect(fse.readlinkSync("symlink")).to.equal("some_path"); | ||
}; | ||
it('sync', () => { | ||
jetpack.symlink('some_path', 'symlink'); | ||
it("sync", () => { | ||
jetpack.symlink("some_path", "symlink"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.symlinkAsync('some_path', 'symlink') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.symlinkAsync("some_path", "symlink").then(() => { | ||
expectations(); | ||
@@ -32,15 +31,14 @@ done(); | ||
describe('can create nonexistent parent directories', () => { | ||
describe("can create nonexistent parent directories", () => { | ||
const expectations = () => { | ||
expect(fse.lstatSync('a/b/symlink').isSymbolicLink()).to.equal(true); | ||
expect(fse.lstatSync("a/b/symlink").isSymbolicLink()).to.equal(true); | ||
}; | ||
it('sync', () => { | ||
jetpack.symlink('whatever', 'a/b/symlink'); | ||
it("sync", () => { | ||
jetpack.symlink("whatever", "a/b/symlink"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.symlinkAsync('whatever', 'a/b/symlink') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.symlinkAsync("whatever", "a/b/symlink").then(() => { | ||
expectations(); | ||
@@ -52,23 +50,22 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('a/b'); | ||
fse.mkdirsSync("a/b"); | ||
}; | ||
const expectations = () => { | ||
expect(fse.lstatSync('a/b/symlink').isSymbolicLink()).to.equal(true); | ||
expect(fse.lstatSync("a/b/symlink").isSymbolicLink()).to.equal(true); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a/b'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a/b"); | ||
preparations(); | ||
jetContext.symlink('whatever', 'symlink'); | ||
jetContext.symlink("whatever", "symlink"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a/b'); | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a/b"); | ||
preparations(); | ||
jetContext.symlinkAsync('whatever', 'symlink') | ||
.then(() => { | ||
jetContext.symlinkAsync("whatever", "symlink").then(() => { | ||
expectations(); | ||
@@ -80,14 +77,22 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.symlink, methodName: 'symlink' }, | ||
{ type: 'async', method: jetpack.symlinkAsync, methodName: 'symlinkAsync' }, | ||
{ type: "sync", method: jetpack.symlink, methodName: "symlink" }, | ||
{ | ||
type: "async", | ||
method: jetpack.symlinkAsync, | ||
methodName: "symlinkAsync" | ||
} | ||
]; | ||
describe('"symlinkValue" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined, 'abc'); | ||
}).to.throw(`Argument "symlinkValue" passed to ${test.methodName}(symlinkValue, path) must be a string. Received undefined`); | ||
test.method(undefined, "abc"); | ||
}).to.throw( | ||
`Argument "symlinkValue" passed to ${ | ||
test.methodName | ||
}(symlinkValue, path) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -98,7 +103,11 @@ }); | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('xyz', undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(symlinkValue, path) must be a string. Received undefined`); | ||
test.method("xyz", undefined); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(symlinkValue, path) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -105,0 +114,0 @@ }); |
@@ -1,9 +0,9 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fsNode = require('fs'); | ||
const expect = require('chai').expect; | ||
const fs = require('../../lib/utils/fs'); | ||
const fsNode = require("fs"); | ||
const expect = require("chai").expect; | ||
const fs = require("../../lib/utils/fs"); | ||
describe('promised fs', () => { | ||
it('contains all the same keys as the node fs module', () => { | ||
describe("promised fs", () => { | ||
it("contains all the same keys as the node fs module", () => { | ||
const originalKeys = Object.keys(fsNode); | ||
@@ -10,0 +10,0 @@ const adaptedKeys = Object.keys(fs); |
@@ -1,189 +0,189 @@ | ||
'use strict'; | ||
"use strict"; | ||
const expect = require('chai').expect; | ||
const matcher = require('../../lib/utils/matcher'); | ||
const expect = require("chai").expect; | ||
const matcher = require("../../lib/utils/matcher"); | ||
describe('matcher', () => { | ||
it('can test against one pattern passed as a string', () => { | ||
const test = matcher.create('/', 'a'); | ||
expect(test('/a')).to.equal(true); | ||
expect(test('/b')).to.equal(false); | ||
describe("matcher", () => { | ||
it("can test against one pattern passed as a string", () => { | ||
const test = matcher.create("/", "a"); | ||
expect(test("/a")).to.equal(true); | ||
expect(test("/b")).to.equal(false); | ||
}); | ||
it('can test against many patterns passed as an array', () => { | ||
const test = matcher.create('/', ['a', 'b']); | ||
expect(test('/a')).to.equal(true); | ||
expect(test('/b')).to.equal(true); | ||
expect(test('/c')).to.equal(false); | ||
it("can test against many patterns passed as an array", () => { | ||
const test = matcher.create("/", ["a", "b"]); | ||
expect(test("/a")).to.equal(true); | ||
expect(test("/b")).to.equal(true); | ||
expect(test("/c")).to.equal(false); | ||
}); | ||
describe('pattern types', () => { | ||
it('only basename', () => { | ||
const test = matcher.create('/', 'a'); | ||
expect(test('/a')).to.equal(true); | ||
expect(test('/b/a')).to.equal(true); | ||
expect(test('/a/b')).to.equal(false); | ||
describe("pattern types", () => { | ||
it("only basename", () => { | ||
const test = matcher.create("/", "a"); | ||
expect(test("/a")).to.equal(true); | ||
expect(test("/b/a")).to.equal(true); | ||
expect(test("/a/b")).to.equal(false); | ||
}); | ||
it('absolute', () => { | ||
let test = matcher.create('/', ['/b']); | ||
expect(test('/b')).to.equal(true); | ||
expect(test('/a/b')).to.equal(false); | ||
test = matcher.create('/a', ['/b']); | ||
expect(test('/a/b')).to.equal(false); | ||
it("absolute", () => { | ||
let test = matcher.create("/", ["/b"]); | ||
expect(test("/b")).to.equal(true); | ||
expect(test("/a/b")).to.equal(false); | ||
test = matcher.create("/a", ["/b"]); | ||
expect(test("/a/b")).to.equal(false); | ||
}); | ||
it('relative with ./', () => { | ||
const test = matcher.create('/a', ['./b']); | ||
expect(test('/a/b')).to.equal(true); | ||
expect(test('/b')).to.equal(false); | ||
it("relative with ./", () => { | ||
const test = matcher.create("/a", ["./b"]); | ||
expect(test("/a/b")).to.equal(true); | ||
expect(test("/b")).to.equal(false); | ||
}); | ||
it('relative (because has slash inside)', () => { | ||
const test = matcher.create('/a', ['b/c']); | ||
expect(test('/a/b/c')).to.equal(true); | ||
expect(test('/b/c')).to.equal(false); | ||
it("relative (because has slash inside)", () => { | ||
const test = matcher.create("/a", ["b/c"]); | ||
expect(test("/a/b/c")).to.equal(true); | ||
expect(test("/b/c")).to.equal(false); | ||
}); | ||
}); | ||
describe('possible tokens', () => { | ||
it('*', () => { | ||
let test = matcher.create('/', ['*']); | ||
expect(test('/a')).to.equal(true); | ||
expect(test('/a/b.txt')).to.equal(true); | ||
describe("possible tokens", () => { | ||
it("*", () => { | ||
let test = matcher.create("/", ["*"]); | ||
expect(test("/a")).to.equal(true); | ||
expect(test("/a/b.txt")).to.equal(true); | ||
test = matcher.create('/', ['a*b']); | ||
expect(test('/ab')).to.equal(true); | ||
expect(test('/a_b')).to.equal(true); | ||
expect(test('/a__b')).to.equal(true); | ||
test = matcher.create("/", ["a*b"]); | ||
expect(test("/ab")).to.equal(true); | ||
expect(test("/a_b")).to.equal(true); | ||
expect(test("/a__b")).to.equal(true); | ||
}); | ||
it('**', () => { | ||
let test = matcher.create('/', ['**']); | ||
expect(test('/a')).to.equal(true); | ||
expect(test('/a/b')).to.equal(true); | ||
it("**", () => { | ||
let test = matcher.create("/", ["**"]); | ||
expect(test("/a")).to.equal(true); | ||
expect(test("/a/b")).to.equal(true); | ||
test = matcher.create('/', ['a/**/d']); | ||
expect(test('/a/d')).to.equal(true); | ||
expect(test('/a/b/d')).to.equal(true); | ||
expect(test('/a/b/c/d')).to.equal(true); | ||
expect(test('/a')).to.equal(false); | ||
expect(test('/d')).to.equal(false); | ||
test = matcher.create("/", ["a/**/d"]); | ||
expect(test("/a/d")).to.equal(true); | ||
expect(test("/a/b/d")).to.equal(true); | ||
expect(test("/a/b/c/d")).to.equal(true); | ||
expect(test("/a")).to.equal(false); | ||
expect(test("/d")).to.equal(false); | ||
}); | ||
it('**/something', () => { | ||
const test = matcher.create('/', ['**/a']); | ||
expect(test('/a')).to.equal(true); | ||
expect(test('/x/a')).to.equal(true); | ||
expect(test('/x/y/a')).to.equal(true); | ||
expect(test('/a/b')).to.equal(false); | ||
it("**/something", () => { | ||
const test = matcher.create("/", ["**/a"]); | ||
expect(test("/a")).to.equal(true); | ||
expect(test("/x/a")).to.equal(true); | ||
expect(test("/x/y/a")).to.equal(true); | ||
expect(test("/a/b")).to.equal(false); | ||
}); | ||
it('@(pattern|pattern) - exactly one of patterns', () => { | ||
const test = matcher.create('/', ['@(foo|bar)']); | ||
expect(test('/foo')).to.equal(true); | ||
expect(test('/bar')).to.equal(true); | ||
expect(test('/foobar')).to.equal(false); | ||
it("@(pattern|pattern) - exactly one of patterns", () => { | ||
const test = matcher.create("/", ["@(foo|bar)"]); | ||
expect(test("/foo")).to.equal(true); | ||
expect(test("/bar")).to.equal(true); | ||
expect(test("/foobar")).to.equal(false); | ||
}); | ||
it('+(pattern|pattern) - one or more of patterns', () => { | ||
const test = matcher.create('/', ['+(foo|bar)']); | ||
expect(test('/foo')).to.equal(true); | ||
expect(test('/bar')).to.equal(true); | ||
expect(test('/foobar')).to.equal(true); | ||
expect(test('/foobarbaz')).to.equal(false); | ||
it("+(pattern|pattern) - one or more of patterns", () => { | ||
const test = matcher.create("/", ["+(foo|bar)"]); | ||
expect(test("/foo")).to.equal(true); | ||
expect(test("/bar")).to.equal(true); | ||
expect(test("/foobar")).to.equal(true); | ||
expect(test("/foobarbaz")).to.equal(false); | ||
}); | ||
it('?(pattern|pattern) - zero or one of patterns', () => { | ||
const test = matcher.create('/', ['?(foo|bar)1']); | ||
expect(test('/1')).to.equal(true); | ||
expect(test('/foo1')).to.equal(true); | ||
expect(test('/bar1')).to.equal(true); | ||
expect(test('/foobar1')).to.equal(false); | ||
it("?(pattern|pattern) - zero or one of patterns", () => { | ||
const test = matcher.create("/", ["?(foo|bar)1"]); | ||
expect(test("/1")).to.equal(true); | ||
expect(test("/foo1")).to.equal(true); | ||
expect(test("/bar1")).to.equal(true); | ||
expect(test("/foobar1")).to.equal(false); | ||
}); | ||
it('*(pattern|pattern) - zero or more of patterns', () => { | ||
const test = matcher.create('/', ['*(foo|bar)1']); | ||
expect(test('/1')).to.equal(true); | ||
expect(test('/foo1')).to.equal(true); | ||
expect(test('/bar1')).to.equal(true); | ||
expect(test('/foobar1')).to.equal(true); | ||
expect(test('/barfoo1')).to.equal(true); | ||
expect(test('/foofoo1')).to.equal(true); | ||
it("*(pattern|pattern) - zero or more of patterns", () => { | ||
const test = matcher.create("/", ["*(foo|bar)1"]); | ||
expect(test("/1")).to.equal(true); | ||
expect(test("/foo1")).to.equal(true); | ||
expect(test("/bar1")).to.equal(true); | ||
expect(test("/foobar1")).to.equal(true); | ||
expect(test("/barfoo1")).to.equal(true); | ||
expect(test("/foofoo1")).to.equal(true); | ||
}); | ||
it('{a,b}', () => { | ||
const test = matcher.create('/', ['*.{jpg,png}']); | ||
expect(test('a.jpg')).to.equal(true); | ||
expect(test('b.png')).to.equal(true); | ||
expect(test('c.txt')).to.equal(false); | ||
it("{a,b}", () => { | ||
const test = matcher.create("/", ["*.{jpg,png}"]); | ||
expect(test("a.jpg")).to.equal(true); | ||
expect(test("b.png")).to.equal(true); | ||
expect(test("c.txt")).to.equal(false); | ||
}); | ||
it('?', () => { | ||
const test = matcher.create('/', ['a?c']); | ||
expect(test('/abc')).to.equal(true); | ||
expect(test('/ac')).to.equal(false); | ||
expect(test('/abbc')).to.equal(false); | ||
it("?", () => { | ||
const test = matcher.create("/", ["a?c"]); | ||
expect(test("/abc")).to.equal(true); | ||
expect(test("/ac")).to.equal(false); | ||
expect(test("/abbc")).to.equal(false); | ||
}); | ||
it('[...] - characters range', () => { | ||
const test = matcher.create('/', ['[0-9][0-9]']); | ||
expect(test('/78')).to.equal(true); | ||
expect(test('/a78')).to.equal(false); | ||
it("[...] - characters range", () => { | ||
const test = matcher.create("/", ["[0-9][0-9]"]); | ||
expect(test("/78")).to.equal(true); | ||
expect(test("/a78")).to.equal(false); | ||
}); | ||
it('combining different tokens together', () => { | ||
const test = matcher.create('/', ['+(f?o|bar*)']); | ||
expect(test('/f0o')).to.equal(true); | ||
expect(test('/f_o')).to.equal(true); | ||
expect(test('/bar')).to.equal(true); | ||
expect(test('/bar_')).to.equal(true); | ||
expect(test('/f_obar123')).to.equal(true); | ||
expect(test('/f__obar123')).to.equal(false); | ||
it("combining different tokens together", () => { | ||
const test = matcher.create("/", ["+(f?o|bar*)"]); | ||
expect(test("/f0o")).to.equal(true); | ||
expect(test("/f_o")).to.equal(true); | ||
expect(test("/bar")).to.equal(true); | ||
expect(test("/bar_")).to.equal(true); | ||
expect(test("/f_obar123")).to.equal(true); | ||
expect(test("/f__obar123")).to.equal(false); | ||
}); | ||
it('comment character # has no special meaning', () => { | ||
const test = matcher.create('/', ['#a']); | ||
expect(test('/#a')).to.equal(true); | ||
it("comment character # has no special meaning", () => { | ||
const test = matcher.create("/", ["#a"]); | ||
expect(test("/#a")).to.equal(true); | ||
}); | ||
}); | ||
describe('negation', () => { | ||
it('selects everything except negated', () => { | ||
const test = matcher.create('/', '!abc'); | ||
expect(test('/abc')).to.equal(false); | ||
expect(test('/xyz')).to.equal(true); | ||
describe("negation", () => { | ||
it("selects everything except negated", () => { | ||
const test = matcher.create("/", "!abc"); | ||
expect(test("/abc")).to.equal(false); | ||
expect(test("/xyz")).to.equal(true); | ||
}); | ||
it('selects everything except negated (multiple patterns)', () => { | ||
const test = matcher.create('/', ['!abc', '!xyz']); | ||
expect(test('/abc')).to.equal(false); | ||
expect(test('/xyz')).to.equal(false); | ||
expect(test('/whatever')).to.equal(true); | ||
it("selects everything except negated (multiple patterns)", () => { | ||
const test = matcher.create("/", ["!abc", "!xyz"]); | ||
expect(test("/abc")).to.equal(false); | ||
expect(test("/xyz")).to.equal(false); | ||
expect(test("/whatever")).to.equal(true); | ||
}); | ||
it('filters previous match if negation is farther in order', () => { | ||
const test = matcher.create('/', ['abc', '123', '!/xyz/**', '!789/**']); | ||
expect(test('/abc')).to.equal(true); | ||
expect(test('/456/123')).to.equal(true); | ||
expect(test('/xyz/abc')).to.equal(false); | ||
expect(test('/789/123')).to.equal(false); | ||
expect(test('/whatever')).to.equal(false); | ||
it("filters previous match if negation is farther in order", () => { | ||
const test = matcher.create("/", ["abc", "123", "!/xyz/**", "!789/**"]); | ||
expect(test("/abc")).to.equal(true); | ||
expect(test("/456/123")).to.equal(true); | ||
expect(test("/xyz/abc")).to.equal(false); | ||
expect(test("/789/123")).to.equal(false); | ||
expect(test("/whatever")).to.equal(false); | ||
}); | ||
}); | ||
describe('dotfiles', () => { | ||
it('has no problem with matching dotfile', () => { | ||
const test = matcher.create('/', '.foo'); | ||
expect(test('/.foo')).to.equal(true); | ||
expect(test('/foo')).to.equal(false); | ||
describe("dotfiles", () => { | ||
it("has no problem with matching dotfile", () => { | ||
const test = matcher.create("/", ".foo"); | ||
expect(test("/.foo")).to.equal(true); | ||
expect(test("/foo")).to.equal(false); | ||
}); | ||
it('dotfile negation', () => { | ||
let test = matcher.create('/', ['abc', '!.foo/**']); | ||
expect(test('/.foo/abc')).to.equal(false); | ||
test = matcher.create('/', ['abc', '!.foo/**']); | ||
expect(test('/foo/abc')).to.equal(true); | ||
it("dotfile negation", () => { | ||
let test = matcher.create("/", ["abc", "!.foo/**"]); | ||
expect(test("/.foo/abc")).to.equal(false); | ||
test = matcher.create("/", ["abc", "!.foo/**"]); | ||
expect(test("/foo/abc")).to.equal(true); | ||
}); | ||
}); | ||
}); |
@@ -1,73 +0,73 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const pathUtil = require('path'); | ||
const expect = require('chai').expect; | ||
const helper = require('../helper'); | ||
const walker = require('../../lib/utils/tree_walker'); | ||
const fse = require("fs-extra"); | ||
const pathUtil = require("path"); | ||
const expect = require("chai").expect; | ||
const helper = require("../helper"); | ||
const walker = require("../../lib/utils/tree_walker"); | ||
describe('tree walker', () => { | ||
describe("tree walker", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('inspects all files and folders recursively and returns them one by one', () => { | ||
describe("inspects all files and folders recursively and returns them one by one", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/a.txt', 'a'); | ||
fse.outputFileSync('a/b/z1.txt', 'z1'); | ||
fse.outputFileSync('a/b/z2.txt', 'z2'); | ||
fse.mkdirsSync('a/b/c'); | ||
fse.outputFileSync("a/a.txt", "a"); | ||
fse.outputFileSync("a/b/z1.txt", "z1"); | ||
fse.outputFileSync("a/b/z2.txt", "z2"); | ||
fse.mkdirsSync("a/b/c"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('a'), | ||
path: pathUtil.resolve("a"), | ||
item: { | ||
type: 'dir', | ||
name: 'a', | ||
}, | ||
type: "dir", | ||
name: "a" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'a.txt'), | ||
path: pathUtil.resolve("a", "a.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'a.txt', | ||
size: 1, | ||
}, | ||
type: "file", | ||
name: "a.txt", | ||
size: 1 | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b'), | ||
path: pathUtil.resolve("a", "b"), | ||
item: { | ||
type: 'dir', | ||
name: 'b', | ||
}, | ||
type: "dir", | ||
name: "b" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b', 'c'), | ||
path: pathUtil.resolve("a", "b", "c"), | ||
item: { | ||
type: 'dir', | ||
name: 'c', | ||
}, | ||
type: "dir", | ||
name: "c" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b', 'z1.txt'), | ||
path: pathUtil.resolve("a", "b", "z1.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'z1.txt', | ||
size: 2, | ||
}, | ||
type: "file", | ||
name: "z1.txt", | ||
size: 2 | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b', 'z2.txt'), | ||
path: pathUtil.resolve("a", "b", "z2.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'z2.txt', | ||
size: 2, | ||
}, | ||
}, | ||
type: "file", | ||
name: "z2.txt", | ||
size: 2 | ||
} | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('a'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("a"); | ||
const data = []; | ||
@@ -81,85 +81,86 @@ preparations(); | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('a'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("a"); | ||
const data = []; | ||
preparations(); | ||
const st = walker.stream(absoluteStartingPath, {}) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, {}) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('can walk through many nested directories', () => { | ||
describe("can walk through many nested directories", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('a/b/x/z1.txt', 'z1'); | ||
fse.outputFileSync('a/c/y/z2.txt', 'z2'); | ||
fse.outputFileSync("a/b/x/z1.txt", "z1"); | ||
fse.outputFileSync("a/c/y/z2.txt", "z2"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('a'), | ||
path: pathUtil.resolve("a"), | ||
item: { | ||
type: 'dir', | ||
name: 'a', | ||
}, | ||
type: "dir", | ||
name: "a" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b'), | ||
path: pathUtil.resolve("a", "b"), | ||
item: { | ||
type: 'dir', | ||
name: 'b', | ||
}, | ||
type: "dir", | ||
name: "b" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b', 'x'), | ||
path: pathUtil.resolve("a", "b", "x"), | ||
item: { | ||
type: 'dir', | ||
name: 'x', | ||
}, | ||
type: "dir", | ||
name: "x" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b', 'x', 'z1.txt'), | ||
path: pathUtil.resolve("a", "b", "x", "z1.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'z1.txt', | ||
size: 2, | ||
}, | ||
type: "file", | ||
name: "z1.txt", | ||
size: 2 | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'c'), | ||
path: pathUtil.resolve("a", "c"), | ||
item: { | ||
type: 'dir', | ||
name: 'c', | ||
}, | ||
type: "dir", | ||
name: "c" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'c', 'y'), | ||
path: pathUtil.resolve("a", "c", "y"), | ||
item: { | ||
type: 'dir', | ||
name: 'y', | ||
}, | ||
type: "dir", | ||
name: "y" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'c', 'y', 'z2.txt'), | ||
path: pathUtil.resolve("a", "c", "y", "z2.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'z2.txt', | ||
size: 2, | ||
}, | ||
}, | ||
type: "file", | ||
name: "z2.txt", | ||
size: 2 | ||
} | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('a'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("a"); | ||
const data = []; | ||
@@ -173,61 +174,61 @@ preparations(); | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('a'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("a"); | ||
const data = []; | ||
preparations(); | ||
const st = walker.stream(absoluteStartingPath, {}) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, {}) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe("won't penetrate folder tree deeper than maxLevelsDeep option tells", () => { | ||
const options = { | ||
maxLevelsDeep: 1, | ||
maxLevelsDeep: 1 | ||
}; | ||
const preparations = () => { | ||
fse.outputFileSync('a/a.txt', 'a'); | ||
fse.outputFileSync('a/b/z1.txt', 'z1'); | ||
fse.outputFileSync("a/a.txt", "a"); | ||
fse.outputFileSync("a/b/z1.txt", "z1"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('a'), | ||
path: pathUtil.resolve("a"), | ||
item: { | ||
type: 'dir', | ||
name: 'a', | ||
}, | ||
type: "dir", | ||
name: "a" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'a.txt'), | ||
path: pathUtil.resolve("a", "a.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'a.txt', | ||
size: 1, | ||
}, | ||
type: "file", | ||
name: "a.txt", | ||
size: 1 | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('a', 'b'), | ||
path: pathUtil.resolve("a", "b"), | ||
item: { | ||
type: 'dir', | ||
name: 'b', | ||
}, | ||
}, | ||
type: "dir", | ||
name: "b" | ||
} | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('a'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("a"); | ||
const data = []; | ||
@@ -241,40 +242,41 @@ preparations(); | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('a'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("a"); | ||
const data = []; | ||
preparations(); | ||
const st = walker.stream(absoluteStartingPath, options) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, options) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('will do fine with empty directory as entry point', () => { | ||
describe("will do fine with empty directory as entry point", () => { | ||
const preparations = () => { | ||
fse.mkdirsSync('abc'); | ||
fse.mkdirsSync("abc"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('abc'), | ||
path: pathUtil.resolve("abc"), | ||
item: { | ||
type: 'dir', | ||
name: 'abc', | ||
}, | ||
}, | ||
type: "dir", | ||
name: "abc" | ||
} | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('abc'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("abc"); | ||
const data = []; | ||
@@ -288,41 +290,42 @@ preparations(); | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('abc'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("abc"); | ||
const data = []; | ||
preparations(); | ||
const st = walker.stream(absoluteStartingPath, {}) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, {}) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('will do fine with file as entry point', () => { | ||
describe("will do fine with file as entry point", () => { | ||
const preparations = () => { | ||
fse.outputFileSync('abc.txt', 'abc'); | ||
fse.outputFileSync("abc.txt", "abc"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('abc.txt'), | ||
path: pathUtil.resolve("abc.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'abc.txt', | ||
size: 3, | ||
}, | ||
}, | ||
type: "file", | ||
name: "abc.txt", | ||
size: 3 | ||
} | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('abc.txt'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("abc.txt"); | ||
const data = []; | ||
@@ -336,33 +339,34 @@ preparations(); | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('abc.txt'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("abc.txt"); | ||
const data = []; | ||
preparations(); | ||
const st = walker.stream(absoluteStartingPath, {}) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, {}) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('will do fine with nonexistent entry point', () => { | ||
const expectations = (data) => { | ||
describe("will do fine with nonexistent entry point", () => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('abc.txt'), | ||
item: undefined, | ||
}, | ||
path: pathUtil.resolve("abc.txt"), | ||
item: undefined | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('abc.txt'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("abc.txt"); | ||
const data = []; | ||
@@ -375,54 +379,55 @@ walker.sync(absoluteStartingPath, {}, (path, item) => { | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('abc.txt'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("abc.txt"); | ||
const data = []; | ||
const st = walker.stream(absoluteStartingPath, {}) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, {}) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('supports inspect options', () => { | ||
describe("supports inspect options", () => { | ||
const options = { | ||
inspectOptions: { | ||
checksum: 'md5', | ||
}, | ||
checksum: "md5" | ||
} | ||
}; | ||
const preparations = () => { | ||
fse.outputFileSync('abc/a.txt', 'a'); | ||
fse.outputFileSync("abc/a.txt", "a"); | ||
}; | ||
const expectations = (data) => { | ||
const expectations = data => { | ||
expect(data).to.eql([ | ||
{ | ||
path: pathUtil.resolve('abc'), | ||
path: pathUtil.resolve("abc"), | ||
item: { | ||
type: 'dir', | ||
name: 'abc', | ||
}, | ||
type: "dir", | ||
name: "abc" | ||
} | ||
}, | ||
{ | ||
path: pathUtil.resolve('abc', 'a.txt'), | ||
path: pathUtil.resolve("abc", "a.txt"), | ||
item: { | ||
type: 'file', | ||
name: 'a.txt', | ||
type: "file", | ||
name: "a.txt", | ||
size: 1, | ||
md5: '0cc175b9c0f1b6a831c399e269772661', | ||
}, | ||
}, | ||
md5: "0cc175b9c0f1b6a831c399e269772661" | ||
} | ||
} | ||
]); | ||
}; | ||
it('sync', () => { | ||
const absoluteStartingPath = pathUtil.resolve('abc'); | ||
it("sync", () => { | ||
const absoluteStartingPath = pathUtil.resolve("abc"); | ||
const data = []; | ||
@@ -436,20 +441,21 @@ preparations(); | ||
it('async', (done) => { | ||
const absoluteStartingPath = pathUtil.resolve('abc'); | ||
it("async", done => { | ||
const absoluteStartingPath = pathUtil.resolve("abc"); | ||
const data = []; | ||
preparations(); | ||
const st = walker.stream(absoluteStartingPath, options) | ||
.on('readable', () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on('error', done) | ||
.on('end', () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
const st = walker | ||
.stream(absoluteStartingPath, options) | ||
.on("readable", () => { | ||
const a = st.read(); | ||
if (a) { | ||
data.push(a); | ||
} | ||
}) | ||
.on("error", done) | ||
.on("end", () => { | ||
expectations(data); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -1,11 +0,11 @@ | ||
'use strict'; | ||
"use strict"; | ||
const expect = require('chai').expect; | ||
const validate = require('../../lib/utils/validate'); | ||
const expect = require("chai").expect; | ||
const validate = require("../../lib/utils/validate"); | ||
describe('util validate', () => { | ||
describe('validates arguments passed to methods', () => { | ||
it('validates its own input', () => { | ||
describe("util validate", () => { | ||
describe("validates arguments passed to methods", () => { | ||
it("validates its own input", () => { | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', 123, ['foo']); | ||
validate.argument("foo(thing)", "thing", 123, ["foo"]); | ||
}).to.throw('Unknown type "foo"'); | ||
@@ -16,74 +16,79 @@ }); | ||
{ | ||
type: 'string', | ||
article: 'a', | ||
goodValue: 'abc', | ||
type: "string", | ||
article: "a", | ||
goodValue: "abc", | ||
wrongValue: 123, | ||
wrongValueType: 'number', | ||
wrongValueType: "number" | ||
}, | ||
{ | ||
type: 'number', | ||
article: 'a', | ||
type: "number", | ||
article: "a", | ||
goodValue: 123, | ||
wrongValue: 'abc', | ||
wrongValueType: 'string', | ||
wrongValue: "abc", | ||
wrongValueType: "string" | ||
}, | ||
{ | ||
type: 'boolean', | ||
article: 'a', | ||
type: "boolean", | ||
article: "a", | ||
goodValue: true, | ||
wrongValue: 'abc', | ||
wrongValueType: 'string', | ||
wrongValue: "abc", | ||
wrongValueType: "string" | ||
}, | ||
{ | ||
type: 'array', | ||
article: 'an', | ||
type: "array", | ||
article: "an", | ||
goodValue: [], | ||
wrongValue: {}, | ||
wrongValueType: 'object', | ||
wrongValueType: "object" | ||
}, | ||
{ | ||
type: 'object', | ||
article: 'an', | ||
type: "object", | ||
article: "an", | ||
goodValue: {}, | ||
wrongValue: [], | ||
wrongValueType: 'array', | ||
wrongValueType: "array" | ||
}, | ||
{ | ||
type: 'buffer', | ||
article: 'a', | ||
type: "buffer", | ||
article: "a", | ||
goodValue: new Buffer(1), | ||
wrongValue: 123, | ||
wrongValueType: 'number', | ||
wrongValueType: "number" | ||
}, | ||
{ | ||
type: 'null', | ||
article: 'a', | ||
type: "null", | ||
article: "a", | ||
goodValue: null, | ||
wrongValue: 123, | ||
wrongValueType: 'number', | ||
wrongValueType: "number" | ||
}, | ||
{ | ||
type: 'undefined', | ||
article: 'an', | ||
type: "undefined", | ||
article: "an", | ||
goodValue: undefined, | ||
wrongValue: 123, | ||
wrongValueType: 'number', | ||
wrongValueType: "number" | ||
}, | ||
{ | ||
type: 'function', | ||
article: 'a', | ||
goodValue: function () {}, | ||
type: "function", | ||
article: "a", | ||
goodValue: function() {}, | ||
wrongValue: 123, | ||
wrongValueType: 'number', | ||
}, | ||
] | ||
.forEach((test) => { | ||
wrongValueType: "number" | ||
} | ||
].forEach(test => { | ||
it(`validates that given thing is a(n) ${test.type}`, () => { | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', test.goodValue, [test.type]); | ||
validate.argument("foo(thing)", "thing", test.goodValue, [test.type]); | ||
}).not.to.throw(); | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', test.wrongValue, [test.type]); | ||
}).to.throw(`Argument "thing" passed to foo(thing) must be ${test.article} ${test.type}. Received ${test.wrongValueType}`); | ||
validate.argument("foo(thing)", "thing", test.wrongValue, [ | ||
test.type | ||
]); | ||
}).to.throw( | ||
`Argument "thing" passed to foo(thing) must be ${test.article} ${ | ||
test.type | ||
}. Received ${test.wrongValueType}` | ||
); | ||
}); | ||
@@ -93,55 +98,80 @@ }); | ||
[ | ||
{ type: 'string', value: 'abc', expect: 'number' }, | ||
{ type: 'number', value: 123, expect: 'string' }, | ||
{ type: 'boolean', value: true, expect: 'number' }, | ||
{ type: 'array', value: [], expect: 'number' }, | ||
{ type: 'object', value: {}, expect: 'number' }, | ||
{ type: 'buffer', value: new Buffer(1), expect: 'number' }, | ||
{ type: 'null', value: null, expect: 'number' }, | ||
{ type: 'undefined', value: undefined, expect: 'number' }, | ||
{ type: 'function', value: function () {}, expect: 'number' }, | ||
] | ||
.forEach((test) => { | ||
{ type: "string", value: "abc", expect: "number" }, | ||
{ type: "number", value: 123, expect: "string" }, | ||
{ type: "boolean", value: true, expect: "number" }, | ||
{ type: "array", value: [], expect: "number" }, | ||
{ type: "object", value: {}, expect: "number" }, | ||
{ type: "buffer", value: new Buffer(1), expect: "number" }, | ||
{ type: "null", value: null, expect: "number" }, | ||
{ type: "undefined", value: undefined, expect: "number" }, | ||
{ type: "function", value: function() {}, expect: "number" } | ||
].forEach(test => { | ||
it(`can detect wrong type: ${test.type}`, () => { | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', test.value, [test.expect]); | ||
}).to.throw(`Argument "thing" passed to foo(thing) must be a ${test.expect}. Received ${test.type}`); | ||
validate.argument("foo(thing)", "thing", test.value, [test.expect]); | ||
}).to.throw( | ||
`Argument "thing" passed to foo(thing) must be a ${ | ||
test.expect | ||
}. Received ${test.type}` | ||
); | ||
}); | ||
}); | ||
it('supports more than one allowed type', () => { | ||
it("supports more than one allowed type", () => { | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', {}, ['string', 'number', 'boolean']); | ||
}).to.throw('Argument "thing" passed to foo(thing) must be a string or a number or a boolean. Received object'); | ||
validate.argument("foo(thing)", "thing", {}, [ | ||
"string", | ||
"number", | ||
"boolean" | ||
]); | ||
}).to.throw( | ||
'Argument "thing" passed to foo(thing) must be a string or a number or a boolean. Received object' | ||
); | ||
}); | ||
it('validates array internal data', () => { | ||
it("validates array internal data", () => { | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', [1, 2, 3], ['array of number']); | ||
validate.argument( | ||
"foo(thing)", | ||
"thing", | ||
[1, 2, 3], | ||
["array of number"] | ||
); | ||
}).not.to.throw(); | ||
expect(() => { | ||
validate.argument('foo(thing)', 'thing', [1, 2, 'a'], ['array of number']); | ||
}).to.throw('Argument "thing" passed to foo(thing) must be an array of number. Received array of number, string'); | ||
validate.argument( | ||
"foo(thing)", | ||
"thing", | ||
[1, 2, "a"], | ||
["array of number"] | ||
); | ||
}).to.throw( | ||
'Argument "thing" passed to foo(thing) must be an array of number. Received array of number, string' | ||
); | ||
}); | ||
}); | ||
describe('validates options object', () => { | ||
it('options object might be undefined', () => { | ||
describe("validates options object", () => { | ||
it("options object might be undefined", () => { | ||
expect(() => { | ||
validate.options('foo(options)', 'options', undefined, { foo: ['string'] }); | ||
validate.options("foo(options)", "options", undefined, { | ||
foo: ["string"] | ||
}); | ||
}).not.to.throw(); | ||
}); | ||
it('option key in options object is optional (doh!)', () => { | ||
it("option key in options object is optional (doh!)", () => { | ||
expect(() => { | ||
validate.options('foo(options)', 'options', {}, { foo: ['string'] }); | ||
validate.options("foo(options)", "options", {}, { foo: ["string"] }); | ||
}).not.to.throw(); | ||
}); | ||
it('throws if option key definition not found', () => { | ||
it("throws if option key definition not found", () => { | ||
expect(() => { | ||
validate.options('foo(options)', 'options', | ||
validate.options( | ||
"foo(options)", | ||
"options", | ||
{ bar: 123 }, | ||
{ foo: ['string'] } | ||
{ foo: ["string"] } | ||
); | ||
@@ -151,7 +181,9 @@ }).to.throw('Unknown argument "options.bar" passed to foo(options)'); | ||
it('validates option', () => { | ||
it("validates option", () => { | ||
expect(() => { | ||
validate.options('foo(options)', 'options', | ||
{ foo: 'abc' }, | ||
{ foo: ['string'] } | ||
validate.options( | ||
"foo(options)", | ||
"options", | ||
{ foo: "abc" }, | ||
{ foo: ["string"] } | ||
); | ||
@@ -161,9 +193,13 @@ }).not.to.throw(); | ||
expect(() => { | ||
validate.options('foo(options)', 'options', | ||
validate.options( | ||
"foo(options)", | ||
"options", | ||
{ foo: 123 }, | ||
{ foo: ['string'] } | ||
{ foo: ["string"] } | ||
); | ||
}).to.throw('Argument "options.foo" passed to foo(options) must be a string. Received number'); | ||
}).to.throw( | ||
'Argument "options.foo" passed to foo(options) must be a string. Received number' | ||
); | ||
}); | ||
}); | ||
}); |
@@ -1,10 +0,10 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('atomic write', () => { | ||
const filePath = 'file.txt'; | ||
describe("atomic write", () => { | ||
const filePath = "file.txt"; | ||
const tempPath = `${filePath}.__new__`; | ||
@@ -17,14 +17,13 @@ | ||
const expectations = () => { | ||
path(filePath).shouldBeFileWithContent('abc'); | ||
path(filePath).shouldBeFileWithContent("abc"); | ||
path(tempPath).shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
jetpack.write(filePath, 'abc', { atomic: true }); | ||
it("sync", () => { | ||
jetpack.write(filePath, "abc", { atomic: true }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.writeAsync(filePath, 'abc', { atomic: true }) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.writeAsync(filePath, "abc", { atomic: true }).then(() => { | ||
expectations(); | ||
@@ -36,22 +35,21 @@ done(); | ||
describe('overwrite existing file', () => { | ||
describe("overwrite existing file", () => { | ||
const preparations = () => { | ||
fse.outputFileSync(filePath, 'xyz'); | ||
fse.outputFileSync(filePath, "xyz"); | ||
}; | ||
const expectations = () => { | ||
path(filePath).shouldBeFileWithContent('abc'); | ||
path(filePath).shouldBeFileWithContent("abc"); | ||
path(tempPath).shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.write(filePath, 'abc', { atomic: true }); | ||
jetpack.write(filePath, "abc", { atomic: true }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.writeAsync(filePath, 'abc', { atomic: true }) | ||
.then(() => { | ||
jetpack.writeAsync(filePath, "abc", { atomic: true }).then(() => { | ||
expectations(); | ||
@@ -63,24 +61,23 @@ done(); | ||
describe('if previous operation failed', () => { | ||
describe("if previous operation failed", () => { | ||
const preparations = () => { | ||
fse.outputFileSync(filePath, 'xyz'); | ||
fse.outputFileSync(filePath, "xyz"); | ||
// Simulating remained file from interrupted previous write attempt. | ||
fse.outputFileSync(tempPath, '123'); | ||
fse.outputFileSync(tempPath, "123"); | ||
}; | ||
const expectations = () => { | ||
path(filePath).shouldBeFileWithContent('abc'); | ||
path(filePath).shouldBeFileWithContent("abc"); | ||
path(tempPath).shouldNotExist(); | ||
}; | ||
it('sync', () => { | ||
it("sync", () => { | ||
preparations(); | ||
jetpack.write(filePath, 'abc', { atomic: true }); | ||
jetpack.write(filePath, "abc", { atomic: true }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
preparations(); | ||
jetpack.writeAsync(filePath, 'abc', { atomic: true }) | ||
.then(() => { | ||
jetpack.writeAsync(filePath, "abc", { atomic: true }).then(() => { | ||
expectations(); | ||
@@ -87,0 +84,0 @@ done(); |
@@ -1,26 +0,25 @@ | ||
'use strict'; | ||
"use strict"; | ||
const fse = require('fs-extra'); | ||
const expect = require('chai').expect; | ||
const path = require('./assert_path'); | ||
const helper = require('./helper'); | ||
const jetpack = require('..'); | ||
const fse = require("fs-extra"); | ||
const expect = require("chai").expect; | ||
const path = require("./assert_path"); | ||
const helper = require("./helper"); | ||
const jetpack = require(".."); | ||
describe('write', () => { | ||
describe("write", () => { | ||
beforeEach(helper.setCleanTestCwd); | ||
afterEach(helper.switchBackToCorrectCwd); | ||
describe('writes data from string', () => { | ||
describe("writes data from string", () => { | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent('abc'); | ||
path("file.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
jetpack.write('file.txt', 'abc'); | ||
it("sync", () => { | ||
jetpack.write("file.txt", "abc"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.writeAsync('file.txt', 'abc') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.writeAsync("file.txt", "abc").then(() => { | ||
expectations(); | ||
@@ -32,15 +31,14 @@ done(); | ||
describe('writes data from Buffer', () => { | ||
describe("writes data from Buffer", () => { | ||
const expectations = () => { | ||
path('file.txt').shouldBeFileWithContent(new Buffer([11, 22])); | ||
path("file.txt").shouldBeFileWithContent(new Buffer([11, 22])); | ||
}; | ||
it('sync', () => { | ||
jetpack.write('file.txt', new Buffer([11, 22])); | ||
it("sync", () => { | ||
jetpack.write("file.txt", new Buffer([11, 22])); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.writeAsync('file.txt', new Buffer([11, 22])) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.writeAsync("file.txt", new Buffer([11, 22])).then(() => { | ||
expectations(); | ||
@@ -52,20 +50,19 @@ done(); | ||
describe('writes data as JSON', () => { | ||
describe("writes data as JSON", () => { | ||
const obj = { | ||
utf8: 'ąćłźż', | ||
utf8: "ąćłźż" | ||
}; | ||
const expectations = () => { | ||
const content = JSON.parse(fse.readFileSync('file.json', 'utf8')); | ||
const content = JSON.parse(fse.readFileSync("file.json", "utf8")); | ||
expect(content).to.eql(obj); | ||
}; | ||
it('sync', () => { | ||
jetpack.write('file.json', obj); | ||
it("sync", () => { | ||
jetpack.write("file.json", obj); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.writeAsync('file.json', obj) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.writeAsync("file.json", obj).then(() => { | ||
expectations(); | ||
@@ -77,11 +74,11 @@ done(); | ||
describe('written JSON data can be indented', () => { | ||
describe("written JSON data can be indented", () => { | ||
const obj = { | ||
utf8: 'ąćłźż', | ||
utf8: "ąćłźż" | ||
}; | ||
const expectations = () => { | ||
const sizeA = fse.statSync('a.json').size; | ||
const sizeB = fse.statSync('b.json').size; | ||
const sizeC = fse.statSync('c.json').size; | ||
const sizeA = fse.statSync("a.json").size; | ||
const sizeB = fse.statSync("b.json").size; | ||
const sizeC = fse.statSync("c.json").size; | ||
expect(sizeB).to.be.above(sizeA); | ||
@@ -91,16 +88,15 @@ expect(sizeC).to.be.above(sizeB); | ||
it('sync', () => { | ||
jetpack.write('a.json', obj, { jsonIndent: 0 }); | ||
jetpack.write('b.json', obj); // Default indent = 2 | ||
jetpack.write('c.json', obj, { jsonIndent: 4 }); | ||
it("sync", () => { | ||
jetpack.write("a.json", obj, { jsonIndent: 0 }); | ||
jetpack.write("b.json", obj); // Default indent = 2 | ||
jetpack.write("c.json", obj, { jsonIndent: 4 }); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
it("async", done => { | ||
Promise.all([ | ||
jetpack.writeAsync('a.json', obj, { jsonIndent: 0 }), | ||
jetpack.writeAsync('b.json', obj), // Default indent = 2 | ||
jetpack.writeAsync('c.json', obj, { jsonIndent: 4 }), | ||
]) | ||
.then(() => { | ||
jetpack.writeAsync("a.json", obj, { jsonIndent: 0 }), | ||
jetpack.writeAsync("b.json", obj), // Default indent = 2 | ||
jetpack.writeAsync("c.json", obj, { jsonIndent: 4 }) | ||
]).then(() => { | ||
expectations(); | ||
@@ -112,20 +108,19 @@ done(); | ||
describe('writes and reads file as JSON with Date parsing', () => { | ||
describe("writes and reads file as JSON with Date parsing", () => { | ||
const obj = { | ||
date: new Date(), | ||
date: new Date() | ||
}; | ||
const expectations = () => { | ||
const content = JSON.parse(fse.readFileSync('file.json', 'utf8')); | ||
const content = JSON.parse(fse.readFileSync("file.json", "utf8")); | ||
expect(content.date).to.equal(obj.date.toISOString()); | ||
}; | ||
it('sync', () => { | ||
jetpack.write('file.json', obj); | ||
it("sync", () => { | ||
jetpack.write("file.json", obj); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.writeAsync('file.json', obj) | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.writeAsync("file.json", obj).then(() => { | ||
expectations(); | ||
@@ -137,15 +132,14 @@ done(); | ||
describe('can create nonexistent parent directories', () => { | ||
describe("can create nonexistent parent directories", () => { | ||
const expectations = () => { | ||
path('a/b/c.txt').shouldBeFileWithContent('abc'); | ||
path("a/b/c.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
jetpack.write('a/b/c.txt', 'abc'); | ||
it("sync", () => { | ||
jetpack.write("a/b/c.txt", "abc"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
jetpack.writeAsync('a/b/c.txt', 'abc') | ||
.then(() => { | ||
it("async", done => { | ||
jetpack.writeAsync("a/b/c.txt", "abc").then(() => { | ||
expectations(); | ||
@@ -157,17 +151,16 @@ done(); | ||
describe('respects internal CWD of jetpack instance', () => { | ||
describe("respects internal CWD of jetpack instance", () => { | ||
const expectations = () => { | ||
path('a/b/c.txt').shouldBeFileWithContent('abc'); | ||
path("a/b/c.txt").shouldBeFileWithContent("abc"); | ||
}; | ||
it('sync', () => { | ||
const jetContext = jetpack.cwd('a'); | ||
jetContext.write('b/c.txt', 'abc'); | ||
it("sync", () => { | ||
const jetContext = jetpack.cwd("a"); | ||
jetContext.write("b/c.txt", "abc"); | ||
expectations(); | ||
}); | ||
it('async', (done) => { | ||
const jetContext = jetpack.cwd('a'); | ||
jetContext.writeAsync('b/c.txt', 'abc') | ||
.then(() => { | ||
it("async", done => { | ||
const jetContext = jetpack.cwd("a"); | ||
jetContext.writeAsync("b/c.txt", "abc").then(() => { | ||
expectations(); | ||
@@ -179,14 +172,18 @@ done(); | ||
describe('input validation', () => { | ||
describe("input validation", () => { | ||
const tests = [ | ||
{ type: 'sync', method: jetpack.write, methodName: 'write' }, | ||
{ type: 'async', method: jetpack.writeAsync, methodName: 'writeAsync' }, | ||
{ type: "sync", method: jetpack.write, methodName: "write" }, | ||
{ type: "async", method: jetpack.writeAsync, methodName: "writeAsync" } | ||
]; | ||
describe('"path" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method(undefined); | ||
}).to.throw(`Argument "path" passed to ${test.methodName}(path, data, [options]) must be a string. Received undefined`); | ||
}).to.throw( | ||
`Argument "path" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a string. Received undefined` | ||
); | ||
}); | ||
@@ -197,7 +194,11 @@ }); | ||
describe('"data" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', true); | ||
}).to.throw(`Argument "data" passed to ${test.methodName}(path, data, [options]) must be a string or a buffer or an object or an array. Received boolean`); | ||
test.method("abc", true); | ||
}).to.throw( | ||
`Argument "data" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a string or a buffer or an object or an array. Received boolean` | ||
); | ||
}); | ||
@@ -209,7 +210,11 @@ }); | ||
describe('"atomic" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', 'xyz', { atomic: 1 }); | ||
}).to.throw(`Argument "options.atomic" passed to ${test.methodName}(path, data, [options]) must be a boolean. Received number`); | ||
test.method("abc", "xyz", { atomic: 1 }); | ||
}).to.throw( | ||
`Argument "options.atomic" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a boolean. Received number` | ||
); | ||
}); | ||
@@ -219,7 +224,11 @@ }); | ||
describe('"jsonIndent" argument', () => { | ||
tests.forEach((test) => { | ||
tests.forEach(test => { | ||
it(test.type, () => { | ||
expect(() => { | ||
test.method('abc', 'xyz', { jsonIndent: true }); | ||
}).to.throw(`Argument "options.jsonIndent" passed to ${test.methodName}(path, data, [options]) must be a number. Received boolean`); | ||
test.method("abc", "xyz", { jsonIndent: true }); | ||
}).to.throw( | ||
`Argument "options.jsonIndent" passed to ${ | ||
test.methodName | ||
}(path, data, [options]) must be a number. Received boolean` | ||
); | ||
}); | ||
@@ -226,0 +235,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
NPM Shrinkwrap
Supply chain riskPackage contains a shrinkwrap file. This may allow the package to bypass normal install procedures.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
334289
29.6%10
-9.09%9906
34.26%534
3.09%62
-4.62%1
Infinity%