Moved fileOps to _app/fileOps

This commit is contained in:
Danielv123 committed 2018-03-28 20:57:57 +02:00
1 parent 802c21f41e
commit fff1989897
8 files changed
+101 -40

No files matched your search

+117
View File
@@ -0,0 +1,117 @@
const fs = require("fs");
const path = require("path");
// gets newest file in a directory
// dir is directory
// files is array of filenames
// callback(err, filename string);
var getNewestFile = function(dir, files, callback) {
if (!callback) throw new Error("Missing callback");
if (!files || (files && files.length === 0)) {
callback(new Error("No files"));
return;
}
// we are appending the file name to the directory, without the
// "/" we would get paths like /folderfile.txt instead of /folder/file.txt
if(dir[dir.length-1] != "/"){
dir += "/";
}
var newest = { file: files[0] };
var checked = 0;
fs.stat(dir + newest.file, function(err, stats) {
if(err) {
callback(err);
} else {
newest.mtime = stats.mtime;
for (var i = 0; i < files.length; i++) {
var file = files[i];
(function(file) {
fs.stat(file, function(err, stats) {
++checked;
if (stats.mtime.getTime() > newest.mtime.getTime()) {
newest = { file : file, mtime : stats.mtime };
}
if (checked == files.length) {
callback(undefined,newest);
}
});
})(dir + file);
}
}
});
}
// get names of all directories in directory
var getDirectoriesSync = function(srcpath) {
return fs.readdirSync(srcpath).filter(function (file) {
return fs.statSync(path.join(srcpath, file)).isDirectory();
});
}
// get names of all files in a directory
var getFileNamesSync = function(srcpath) {
return fs.readdirSync(srcpath).filter(function (file) {
return !fs.statSync(path.join(srcpath, file)).isDirectory();
});
}
// does what it says on the tin
var deleteFolderRecursiveSync = function(path) {
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(function (file, index) {
var curPath = path + "/" + file;
if (fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursiveSync(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
return true;
} else {
return false;
}
};
var deleteFolderRecursive = function(path){
return new Promise((resolve, reject) => {
fs.readdir(path, (err, files) => {
if(err) reject(err);
let thingsToDelete = files.length;
files.forEach(file => {
let curPath = path + "/" + file;
fs.stat(curPath, (err, stat) => {
if(!err){
if(stat.isDirectory()){
// recurse
deleteFolderRecursive(curPath).then(() => {
whenFilesDeleted();
});
} else {
fs.unlink(curPath, () => {
// console.log("Deleted "+curPath);
whenFilesDeleted();
});
}
} else {
resolve(false);
}
});
});
whenFilesDeleted();
function whenFilesDeleted(){
if(!thingsToDelete--){// var-- instead of --var because we are calling the function once too much and need the delay
fs.rmdir(path, () => {
resolve();
// console.log("Deleted "+path);
});
}
}
});
});
}
module.exports = {
getNewestFile,
getDirectoriesSync,
deleteFolderRecursiveSync,
deleteFolderRecursive,
getFileNamesSync,
}
+134
View File
@@ -0,0 +1,134 @@
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const fileOps = require('./fileOps');
// create folders for testing
function setupTestingEnv(){
if (!fs.existsSync(path.resolve(__dirname, "database"))){
fs.mkdirSync(path.resolve(__dirname, "database"));
}
if (!fs.existsSync(path.resolve(__dirname, "test"))){
fs.mkdirSync(path.resolve(__dirname, "test"));
}
if (!fs.existsSync(path.resolve(__dirname, "test/folder"))){
fs.mkdirSync(path.resolve(__dirname, "test/folder"));
}
if (!fs.existsSync(path.resolve(__dirname, "test/another folder"))){
fs.mkdirSync(path.resolve(__dirname, "test/another folder"));
}
if (!fs.existsSync(path.resolve(__dirname, "test/file.txt"))){
fs.writeFileSync(path.resolve(__dirname, "test/file.txt"), "contents");
}
if (!fs.existsSync(path.resolve(__dirname, "test/another file.txt"))){
fs.writeFileSync(path.resolve(__dirname, "test/another file.txt"), "more contents");
}
// we need this xfile to test a branch in fileOps.getNewestFile()s propagation
if (!fs.existsSync(path.resolve(__dirname, "test/xfile.txt"))){
fs.writeFileSync(path.resolve(__dirname, "test/xfile.txt"), "contents");
}
}
setupTestingEnv();
setupTestingEnv(); // run twice to get branch coverage
describe("fileOps.js", function(){
describe("fileOps.getDirectoriesSync()", function(){
it("gets an array of directory names from a path", function(){
let directories = fileOps.getDirectoriesSync(path.resolve(__dirname, "test"));
// because there are no arrays for some reason
assert(typeof directories == "object");
// they are sorted alphabetically because thats the way it is
assert(directories[0] == "another folder" && directories[1] == "folder");
});
it("does not return any filenames", function(){
let directories = fileOps.getDirectoriesSync(path.resolve(__dirname, "test"));
// this is a function to return directories, not files. So yeah.
assert(!directories.includes("file.txt") && !directories.includes("another file.txt"));
});
it("throws when lacking first argument", function(){
assert.throws(function(){
let files = fileOps.getDirectoriesSync();
}, Error);
});
});
describe("fileOps.getFileNamesSync(path)", function(){
it("gets names of files in directory", function(){
let files = fileOps.getFileNamesSync(path.resolve(__dirname, "test"));
assert(files.length > 0);
assert(files.includes("file.txt") && files.includes("another file.txt"));
});
it("throws when lacking first argument", function(){
assert.throws(function(){
let files = fileOps.getFileNamesSync();
}, Error);
});
});
describe("fileOps.getNewestFile()", function(){
it("gets the newest file in a directory async", function(done){
fileOps.getNewestFile(path.resolve(__dirname, "test/"), fileOps.getFileNamesSync(path.resolve(__dirname, "test")), function(err, newest){
assert(newest && typeof newest.file == "string");
done();
});
});
it("throws if callback is missing", function(){
assert.throws(function(){
fileOps.getNewestFile("test", fileOps.getFileNamesSync(path.resolve(__dirname, "test")));
}, Error);
});
it("executes callback(err) if no files are provided", function(done){
fileOps.getNewestFile(path.resolve(__dirname, "test"), [], function(err, newest){
assert(err && typeof err == "object");
done();
});
});
it("executes callback(err) if launched without a directory", function(done){
fileOps.getNewestFile("", fileOps.getFileNamesSync(path.resolve(__dirname, "test")), function(err, newest){
assert(err);
done();
});
});
it("executes callback(err) when you do stupid shit", function(done){
fileOps.getNewestFile({thisWontWork: "but not crash either"}, {lolz:"yeah..."}, function(err, newest){
assert(err);
// ENOENT: no such file or directory, stat 'C:\**\factorioClusterio\lib\test\undefined'
done();
});
});
});
describe("fileOps.deleteFolderRecursiveSync(path)", function(){
it("deletes a folder and all files and folders in it", function(){
let x = fileOps.deleteFolderRecursiveSync(path.resolve(__dirname, "test"));
assert.throws(function(){
fs.statSync(path.resolve(__dirname, "test"));
}, Error);
assert(x);
// give it some extra time because its sometimes very slow
}).timeout(5000);
it("returns false if you give it an invalid path", function(){
let x = fileOps.deleteFolderRecursiveSync("This isn't a real path");
assert(!x);
});
});
describe("fileOps.deleteFolderRecursive(path)", function(){
it("deletes a folder and all files and folders in it, just like sync version", async function(){
setupTestingEnv();
let x = await fileOps.deleteFolderRecursive(path.resolve(__dirname, "test"));
assert.throws(function(){
fs.statSync(path.resolve(__dirname, "test"));
}, Error);
assert(x === undefined, "Promise version of this function does not have a return value upon success");
return true;
}).timeout(5000);
it("throws like a promise if you give it an invalid path", async function(){
let x = await fileOps.deleteFolderRecursive("Look this path is fake!")
.catch(e => {
assert(e);
assert.equal(e.code, "ENOENT");
return true;
});
});
});
});
+2
View File
@@ -0,0 +1,2 @@
const fileOps = require("./fileOps");
module.exports = fileOps;