Socket
Socket
Sign inDemoInstall

fs-jetpack

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fs-jetpack - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

npm-shrinkwrap.json

63

benchmark/copy.js
/* 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 @@ };

@@ -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 @@ };

@@ -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 @@ });

@@ -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 @@ };

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc