fs-jetpack
Advanced tools
Comparing version 1.2.0 to 1.3.0
/* 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 [![Build Status](https://travis-ci.org/szwacz/fs-jetpack.svg?branch=master)](https://travis-ci.org/szwacz/fs-jetpack) [![Build status](https://ci.appveyor.com/api/projects/status/er206e91fpuuqf58?svg=true)](https://ci.appveyor.com/project/szwacz/fs-jetpack) [![codecov](https://codecov.io/gh/szwacz/fs-jetpack/branch/master/graph/badge.svg)](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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
334289
10
9906
534
62
1