draft: refactor project so it sits on top of a standalone app

This commit is contained in:
2020-05-11 15:34:47 +02:00
parent a9ee5acc1c
commit f97e8455fc
13068 changed files with 1735502 additions and 866 deletions
+22
View File
@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
+65
View File
@@ -0,0 +1,65 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Icon must ends with two \r.
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Windows
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
+14
View File
@@ -0,0 +1,14 @@
language: node_js
node_js:
- "0.10"
- "0.12"
- "iojs"
script: npm run travis
before_install:
- '[ "${TRAVIS_NODE_VERSION}" != "0.10" ] || npm install -g npm'
after_success:
- cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose
- cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js
- rm -rf ./coverage
+29
View File
@@ -0,0 +1,29 @@
# memory-fs
A simple in-memory filesystem. Holds data in a javascript object.
``` javascript
var MemoryFileSystem = require("memory-fs");
var fs = new MemoryFileSystem(); // Optionally pass a javascript object
fs.mkdirpSync("/a/test/dir");
fs.writeFileSync("/a/test/dir/file.txt", "Hello World");
fs.readFileSync("/a/test/dir/file.txt"); // returns Buffer("Hello World")
// Async variantes too
fs.unlink("/a/test/dir/file.txt", function(err) {
// ...
});
fs.readdirSync("/a/test"); // returns ["dir"]
fs.statSync("/a/test/dir").isDirectory(); // returns true
fs.rmdirSync("/a/test/dir");
fs.mkdirpSync("C:\\use\\windows\\style\\paths");
```
## License
Copyright (c) 2012-2014 Tobias Koppers
MIT (http://www.opensource.org/licenses/mit-license.php)
+315
View File
@@ -0,0 +1,315 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var normalize = require("./normalize");
var errors = require("errno");
var stream = require("readable-stream");
var ReadableStream = stream.Readable;
var WritableStream = stream.Writable;
function MemoryFileSystemError(err, path) {
Error.call(this)
if (Error.captureStackTrace)
Error.captureStackTrace(this, arguments.callee)
this.code = err.code;
this.errno = err.errno;
this.message = err.description;
this.path = path;
}
MemoryFileSystemError.prototype = new Error();
function MemoryFileSystem(data) {
this.data = data || {};
}
module.exports = MemoryFileSystem;
function isDir(item) {
if(typeof item !== "object") return false;
return item[""] === true;
}
function isFile(item) {
if(typeof item !== "object") return false;
return !item[""];
}
function pathToArray(path) {
path = normalize(path);
var nix = /^\//.test(path);
if(!nix) {
if(!/^[A-Za-z]:/.test(path)) {
throw new MemoryFileSystemError(errors.code.EINVAL, path);
}
path = path.replace(/[\\\/]+/g, "\\"); // multi slashs
path = path.split(/[\\\/]/);
path[0] = path[0].toUpperCase();
} else {
path = path.replace(/\/+/g, "/"); // multi slashs
path = path.substr(1).split("/");
}
if(!path[path.length-1]) path.pop();
return path;
}
function trueFn() { return true; }
function falseFn() { return false; }
MemoryFileSystem.prototype.meta = function(_path) {
var path = pathToArray(_path);
var current = this.data;
for(var i = 0; i < path.length - 1; i++) {
if(!isDir(current[path[i]]))
return null;
current = current[path[i]];
}
return current[path[i]];
}
MemoryFileSystem.prototype.existsSync = function(_path) {
return !!this.meta(_path);
}
MemoryFileSystem.prototype.statSync = function(_path) {
var current = this.meta(_path);
if(_path === "/" || isDir(current)) {
return {
isFile: falseFn,
isDirectory: trueFn,
isBlockDevice: falseFn,
isCharacterDevice: falseFn,
isSymbolicLink: falseFn,
isFIFO: falseFn,
isSocket: falseFn
};
} else if(isFile(current)) {
return {
isFile: trueFn,
isDirectory: falseFn,
isBlockDevice: falseFn,
isCharacterDevice: falseFn,
isSymbolicLink: falseFn,
isFIFO: falseFn,
isSocket: falseFn
};
} else {
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
}
};
MemoryFileSystem.prototype.readFileSync = function(_path, encoding) {
var path = pathToArray(_path);
var current = this.data;
for(var i = 0; i < path.length - 1; i++) {
if(!isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
current = current[path[i]];
}
if(!isFile(current[path[i]])) {
if(isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
else
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
}
current = current[path[i]];
return encoding ? current.toString(encoding) : current;
};
MemoryFileSystem.prototype.readdirSync = function(_path) {
if(_path === "/") return Object.keys(this.data).filter(Boolean);
var path = pathToArray(_path);
var current = this.data;
for(var i = 0; i < path.length - 1; i++) {
if(!isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
current = current[path[i]];
}
if(!isDir(current[path[i]])) {
if(isFile(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path);
else
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
}
return Object.keys(current[path[i]]).filter(Boolean);
};
MemoryFileSystem.prototype.mkdirpSync = function(_path) {
var path = pathToArray(_path);
if(path.length === 0) return;
var current = this.data;
for(var i = 0; i < path.length; i++) {
if(isFile(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path);
else if(!isDir(current[path[i]]))
current[path[i]] = {"":true};
current = current[path[i]];
}
return;
};
MemoryFileSystem.prototype.mkdirSync = function(_path) {
var path = pathToArray(_path);
if(path.length === 0) return;
var current = this.data;
for(var i = 0; i < path.length - 1; i++) {
if(!isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
current = current[path[i]];
}
if(isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.EEXIST, _path);
else if(isFile(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path);
current[path[i]] = {"":true};
return;
};
MemoryFileSystem.prototype._remove = function(_path, name, testFn) {
var path = pathToArray(_path);
if(path.length === 0) {
throw new MemoryFileSystemError(errors.code.EPERM, _path);
}
var current = this.data;
for(var i = 0; i < path.length - 1; i++) {
if(!isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
current = current[path[i]];
}
if(!testFn(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
delete current[path[i]];
return;
};
MemoryFileSystem.prototype.rmdirSync = function(_path) {
return this._remove(_path, "Directory", isDir);
};
MemoryFileSystem.prototype.unlinkSync = function(_path) {
return this._remove(_path, "File", isFile);
};
MemoryFileSystem.prototype.readlinkSync = function(_path) {
throw new MemoryFileSystemError(errors.code.ENOSYS, _path);
};
MemoryFileSystem.prototype.writeFileSync = function(_path, content, encoding) {
if(!content && !encoding) throw new Error("No content");
var path = pathToArray(_path);
if(path.length === 0) {
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
}
var current = this.data;
for(var i = 0; i < path.length - 1; i++) {
if(!isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
current = current[path[i]];
}
if(isDir(current[path[i]]))
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
current[path[i]] = encoding || typeof content === "string" ? new Buffer(content, encoding) : content;
return;
};
MemoryFileSystem.prototype.join = require("./join");
MemoryFileSystem.prototype.normalize = normalize;
// stream functions
MemoryFileSystem.prototype.createReadStream = function(path, options) {
var stream = new ReadableStream();
var done = false;
var data;
try {
data = this.readFileSync(path);
} catch (e) {
stream._read = function() {
if (done) {
return;
}
done = true;
this.emit('error', e);
this.push(null);
};
return stream;
}
options = options || { };
options.start = options.start || 0;
options.end = options.end || data.length;
stream._read = function() {
if (done) {
return;
}
done = true;
this.push(data.slice(options.start, options.end));
this.push(null);
};
return stream;
};
MemoryFileSystem.prototype.createWriteStream = function(path, options) {
var stream = new WritableStream(), self = this;
try {
// Zero the file and make sure it is writable
this.writeFileSync(path, new Buffer(0));
} catch(e) {
// This or setImmediate?
stream.once('prefinish', function() {
stream.emit('error', e);
});
return stream;
}
var bl = [ ], len = 0;
stream._write = function(chunk, encoding, callback) {
bl.push(chunk);
len += chunk.length;
self.writeFile(path, Buffer.concat(bl, len), callback);
}
return stream;
};
// async functions
["stat", "readdir", "mkdirp", "mkdir", "rmdir", "unlink", "readlink"].forEach(function(fn) {
MemoryFileSystem.prototype[fn] = function(path, callback) {
try {
var result = this[fn + "Sync"](path);
} catch(e) {
return callback(e);
}
return callback(null, result);
};
});
MemoryFileSystem.prototype.exists = function(path, callback) {
return callback(this.existsSync(path));
}
MemoryFileSystem.prototype.readFile = function(path, optArg, callback) {
if(!callback) {
callback = optArg;
optArg = undefined;
}
try {
var result = this.readFileSync(path, optArg);
} catch(e) {
return callback(e);
}
return callback(null, result);
};
MemoryFileSystem.prototype.writeFile = function (path, content, encoding, callback) {
if(!callback) {
callback = encoding;
encoding = undefined;
}
try {
this.writeFileSync(path, content, encoding);
} catch(e) {
return callback(e);
}
return callback();
};
+14
View File
@@ -0,0 +1,14 @@
var normalize = require("./normalize");
var absoluteWinRegExp = /^[A-Z]:([\\\/]|$)/i;
var absoluteNixRegExp = /^\//i;
module.exports = function join(path, request) {
if(request == "") return normalize(path);
if(absoluteWinRegExp.test(request)) return normalize(request.replace(/\//g, "\\"));
if(absoluteNixRegExp.test(request)) return normalize(request);
if(path == "/") return normalize(path + request);
if(absoluteWinRegExp.test(path)) return normalize(path + "\\" + request.replace(/\//g, "\\"));
if(absoluteNixRegExp.test(path)) return normalize(path + "/" + request);
return normalize(path + "/" + request);
};
+38
View File
@@ -0,0 +1,38 @@
var doubleSlashWinRegExp = /\\+/g;
var doubleSlashNixRegExp = /\/+/g;
var currentDirectoryWinMiddleRegExp = /\\(\.\\)+/;
var currentDirectoryWinEndRegExp = /\\\.$/;
var parentDirectoryWinMiddleRegExp = /\\+[^\\]+\\+\.\.\\/;
var parentDirectoryWinEndRegExp1 = /([A-Z]:\\)\\*[^\\]+\\+\.\.$/i;
var parentDirectoryWinEndRegExp2 = /\\+[^\\]+\\+\.\.$/;
var currentDirectoryNixMiddleRegExp = /\/+(\.\/)+/;
var currentDirectoryNixEndRegExp1 = /^\/+\.$/;
var currentDirectoryNixEndRegExp2 = /\/+\.$/;
var parentDirectoryNixMiddleRegExp = /(^|\/[^\/]+)\/+\.\.\/+/;
var parentDirectoryNixEndRegExp1 = /^\/[^\/]+\/+\.\.$/;
var parentDirectoryNixEndRegExp2 = /\/+[^\/]+\/+\.\.$/;
var parentDirectoryNixEndRegExp3 = /^\/+\.\.$/;
// RegExp magic :)
module.exports = function normalize(path) {
while(currentDirectoryWinMiddleRegExp.test(path))
path = path.replace(currentDirectoryWinMiddleRegExp, "\\");
path = path.replace(currentDirectoryWinEndRegExp, "");
while(parentDirectoryWinMiddleRegExp.test(path))
path = path.replace(parentDirectoryWinMiddleRegExp, "\\");
path = path.replace(parentDirectoryWinEndRegExp1, "$1");
path = path.replace(parentDirectoryWinEndRegExp2, "");
while(currentDirectoryNixMiddleRegExp.test(path))
path = path.replace(currentDirectoryNixMiddleRegExp, "/");
path = path.replace(currentDirectoryNixEndRegExp1, "/");
path = path.replace(currentDirectoryNixEndRegExp2, "");
while(parentDirectoryNixMiddleRegExp.test(path))
path = path.replace(parentDirectoryNixMiddleRegExp, "/");
path = path.replace(parentDirectoryNixEndRegExp1, "/");
path = path.replace(parentDirectoryNixEndRegExp2, "");
path = path.replace(parentDirectoryNixEndRegExp3, "/");
return path.replace(doubleSlashWinRegExp, "\\").replace(doubleSlashNixRegExp, "/");
};
+67
View File
@@ -0,0 +1,67 @@
{
"_from": "memory-fs@^0.3.0",
"_id": "memory-fs@0.3.0",
"_inBundle": false,
"_integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=",
"_location": "/memory-fs",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "memory-fs@^0.3.0",
"name": "memory-fs",
"escapedName": "memory-fs",
"rawSpec": "^0.3.0",
"saveSpec": null,
"fetchSpec": "^0.3.0"
},
"_requiredBy": [
"/aspnet-webpack"
],
"_resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz",
"_shasum": "7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20",
"_spec": "memory-fs@^0.3.0",
"_where": "O:\\zero\\zero.Web\\node_modules\\aspnet-webpack",
"author": {
"name": "Tobias Koppers @sokra"
},
"bugs": {
"url": "https://github.com/webpack/memory-fs/issues"
},
"bundleDependencies": false,
"dependencies": {
"errno": "^0.1.3",
"readable-stream": "^2.0.1"
},
"deprecated": false,
"description": "A simple in-memory filesystem. Holds data in a javascript object.",
"devDependencies": {
"bl": "^1.0.0",
"codecov.io": "^0.1.4",
"coveralls": "^2.11.2",
"istanbul": "^0.2.13",
"mocha": "^1.20.1",
"should": "^4.0.4"
},
"directories": {
"test": "test"
},
"homepage": "https://github.com/webpack/memory-fs",
"keywords": [
"fs",
"memory"
],
"license": "MIT",
"main": "lib/MemoryFileSystem.js",
"name": "memory-fs",
"repository": {
"type": "git",
"url": "git+https://github.com/webpack/memory-fs.git"
},
"scripts": {
"cover": "istanbul cover node_modules/mocha/bin/_mocha",
"test": "mocha",
"travis": "npm run cover -- --report lcovonly"
},
"version": "0.3.0"
}
+442
View File
@@ -0,0 +1,442 @@
var bl = require("bl");
var should = require("should");
var MemoryFileSystem = require("../lib/MemoryFileSystem");
describe("directory", function() {
it("should have a empty root directory as startup", function(done) {
var fs = new MemoryFileSystem();
fs.readdirSync("/").should.be.eql([]);
var stat = fs.statSync("/");
stat.isFile().should.be.eql(false);
stat.isDirectory().should.be.eql(true);
fs.readdir("/", function(err, files) {
if(err) throw err;
files.should.be.eql([]);
done();
});
});
it("should make and remove directories (linux style)", function() {
var fs = new MemoryFileSystem();
fs.mkdirSync("/test");
fs.mkdirSync("/test//sub/");
fs.mkdirpSync("/test/sub2");
fs.mkdirSync("/root\\dir");
fs.mkdirpSync("/");
fs.mkdirSync("/");
fs.readdirSync("/").should.be.eql(["test", "root\\dir"]);
fs.readdirSync("/test/").should.be.eql(["sub", "sub2"]);
fs.rmdirSync("/test/sub//");
fs.readdirSync("//test").should.be.eql(["sub2"]);
fs.rmdirSync("/test/sub2");
fs.rmdirSync("/test");
fs.existsSync("/test").should.be.eql(false);
(function() {
fs.readdirSync("/test");
}).should.throw();
fs.readdirSync("/").should.be.eql(["root\\dir"]);
fs.mkdirpSync("/a/depth/sub/dir");
fs.existsSync("/a/depth/sub").should.be.eql(true);
var stat = fs.statSync("/a/depth/sub");
stat.isFile().should.be.eql(false);
stat.isDirectory().should.be.eql(true);
});
it("should make and remove directories (windows style)", function() {
var fs = new MemoryFileSystem();
fs.mkdirSync("C:\\");
fs.mkdirSync("C:\\test");
fs.mkdirSync("C:\\test\\\\sub/");
fs.mkdirpSync("c:\\test/sub2");
fs.mkdirSync("C:\\root-dir");
fs.readdirSync("C:").should.be.eql(["test", "root-dir"]);
fs.readdirSync("C:/test/").should.be.eql(["sub", "sub2"]);
fs.rmdirSync("C:/test\\sub\\\\");
fs.readdirSync("C:\\\\test").should.be.eql(["sub2"]);
fs.rmdirSync("C:\\test\\sub2");
fs.rmdirSync("C:\\test");
fs.existsSync("C:\\test").should.be.eql(false);
(function() {
fs.readdirSync("C:\\test");
}).should.throw();
fs.readdirSync("C:").should.be.eql(["root-dir"]);
fs.mkdirpSync("D:\\a\\depth\\sub\\dir");
fs.existsSync("D:\\a\\depth\\sub").should.be.eql(true);
var stat = fs.statSync("D:\\a\\depth\\sub");
stat.isFile().should.be.eql(false);
stat.isDirectory().should.be.eql(true);
fs.readdirSync("D:\\//a/depth/\\sub").should.be.eql(["dir"]);
});
});
describe("files", function() {
it("should make and remove files", function() {
var fs = new MemoryFileSystem();
fs.mkdirSync("/test");
var buf = new Buffer("Hello World", "utf-8");
fs.writeFileSync("/test/hello-world.txt", buf);
fs.readFileSync("/test/hello-world.txt").should.be.eql(buf);
fs.readFileSync("/test/hello-world.txt", "utf-8").should.be.eql("Hello World");
(function() {
fs.readFileSync("/test/other-file");
}).should.throw();
(function() {
fs.readFileSync("/test/other-file", "utf-8");
}).should.throw();
fs.writeFileSync("/a", "Test", "utf-8");
fs.readFileSync("/a", "utf-8").should.be.eql("Test");
var stat = fs.statSync("/a");
stat.isFile().should.be.eql(true);
stat.isDirectory().should.be.eql(false);
});
});
describe("errors", function() {
it("should fail on invalid paths", function() {
var fs = new MemoryFileSystem();
fs.mkdirpSync("/test/a/b/c");
fs.mkdirpSync("/test/a/bc");
fs.mkdirpSync("/test/abc");
(function() {
fs.mkdirpSync("xyz");
}).should.throw();
(function() {
fs.readdirSync("/test/abc/a/b/c");
}).should.throw();
(function() {
fs.readdirSync("/abc");
}).should.throw();
(function() {
fs.statSync("/abc");
}).should.throw();
(function() {
fs.mkdirSync("/test/a/d/b/c");
}).should.throw();
(function() {
fs.writeFileSync("/test/a/d/b/c", "Hello");
}).should.throw();
(function() {
fs.readFileSync("/test/a/d/b/c");
}).should.throw();
(function() {
fs.readFileSync("/test/abcd");
}).should.throw();
(function() {
fs.mkdirSync("/test/abcd/dir");
}).should.throw();
(function() {
fs.unlinkSync("/test/abcd");
}).should.throw();
(function() {
fs.unlinkSync("/test/abcd/file");
}).should.throw();
(function() {
fs.statSync("/test/a/d/b/c");
}).should.throw();
(function() {
fs.statSync("/test/abcd");
}).should.throw();
fs.mkdir("/test/a/d/b/c", function(err) {
err.should.be.instanceof(Error);
});
});
it("should fail incorrect arguments", function() {
var fs = new MemoryFileSystem();
(function() {
fs.writeFileSync("/test");
}).should.throw();
});
it("should fail on wrong type", function() {
var fs = new MemoryFileSystem();
fs.mkdirpSync("/test/dir");
fs.mkdirpSync("/test/dir");
fs.writeFileSync("/test/file", "Hello");
(function() {
fs.writeFileSync("/test/dir", "Hello");
}).should.throw();
(function() {
fs.readFileSync("/test/dir");
}).should.throw();
(function() {
fs.writeFileSync("/", "Hello");
}).should.throw();
(function() {
fs.rmdirSync("/");
}).should.throw();
(function() {
fs.unlinkSync("/");
}).should.throw();
(function() {
fs.mkdirSync("/test/dir");
}).should.throw();
(function() {
fs.mkdirSync("/test/file");
}).should.throw();
(function() {
fs.mkdirpSync("/test/file");
}).should.throw();
(function() {
fs.readdirSync("/test/file");
}).should.throw();
fs.readdirSync("/test/").should.be.eql(["dir", "file"]);
});
it("should throw on readlink", function() {
var fs = new MemoryFileSystem();
fs.mkdirpSync("/test/dir");
(function() {
fs.readlinkSync("/");
}).should.throw();
(function() {
fs.readlinkSync("/link");
}).should.throw();
(function() {
fs.readlinkSync("/test");
}).should.throw();
(function() {
fs.readlinkSync("/test/dir");
}).should.throw();
(function() {
fs.readlinkSync("/test/dir/link");
}).should.throw();
});
});
describe("async", function() {
it("should be able to use the async versions", function(done) {
var fs = new MemoryFileSystem();
fs.mkdirp("/test/dir", function(err) {
if(err) throw err;
fs.writeFile("/test/dir/a", "Hello", function(err) {
if(err) throw err;
fs.writeFile("/test/dir/b", "World", "utf-8", function(err) {
if(err) throw err;
fs.readFile("/test/dir/a", "utf-8", function(err, content) {
if(err) throw err;
content.should.be.eql("Hello");
fs.readFile("/test/dir/b", function(err, content) {
if(err) throw err;
content.should.be.eql(new Buffer("World"));
fs.exists("/test/dir/b", function(exists) {
exists.should.be.eql(true);
done();
});
});
});
});
});
});
});
it("should return errors", function(done) {
var fs = new MemoryFileSystem();
fs.readFile("/fail/file", function(err, content) {
err.should.be.instanceof(Error);
fs.writeFile("/fail/file", "", function(err) {
err.should.be.instanceof(Error);
done();
});
});
});
});
describe("streams", function() {
describe("writable streams", function() {
it("should write files", function() {
var fs = new MemoryFileSystem();
fs.createWriteStream("/file").end("Hello");
fs.readFileSync("/file", "utf8").should.be.eql("Hello");
});
it("should zero files", function() {
var fs = new MemoryFileSystem();
fs.createWriteStream("/file").end();
fs.readFileSync("/file", "utf8").should.be.eql("");
});
it("should accept pipes", function(done) {
// TODO: Any way to avoid the asyncness of this?
var fs = new MemoryFileSystem();
bl(new Buffer("Hello"))
.pipe(fs.createWriteStream("/file"))
.once('finish', function() {
fs.readFileSync("/file", "utf8").should.be.eql("Hello");
done();
});
});
it("should propagate errors", function(done) {
var fs = new MemoryFileSystem();
var stream = fs.createWriteStream("file");
var err = false;
stream.once('error', function() {
err = true;
}).once('finish', function() {
err.should.eql(true);
done();
});
stream.end();
});
});
describe("readable streams", function() {
it("should read files", function(done) {
var fs = new MemoryFileSystem();
fs.writeFileSync("/file", "Hello");
fs.createReadStream("/file").pipe(bl(function(err, data) {
data.toString('utf8').should.be.eql("Hello");
done();
}));
});
it("should respect start/end", function(done) {
var fs = new MemoryFileSystem();
fs.writeFileSync("/file", "Hello");
fs.createReadStream("/file", {
start: 1,
end: 3
}).pipe(bl(function(err, data) {
data.toString('utf8').should.be.eql("el");
done();
}));
});
it("should propagate errors", function(done) {
var fs = new MemoryFileSystem();
var stream = fs.createReadStream("file");
var err = false;
// Why does this dummy event need to be here? It looks like it
// either has to be this or data before the stream will actually
// do anything.
stream.on('readable', function() { }).on('error', function() {
err = true;
}).on('end', function() {
err.should.eql(true);
done();
});
stream.read(0);
});
});
});
describe("normalize", function() {
it("should normalize paths", function() {
var fs = new MemoryFileSystem();
fs.normalize("/a/b/c").should.be.eql("/a/b/c");
fs.normalize("/a//b/c").should.be.eql("/a/b/c");
fs.normalize("/a//b//c").should.be.eql("/a/b/c");
fs.normalize("//a//b//c").should.be.eql("/a/b/c");
fs.normalize("/a/////b/c").should.be.eql("/a/b/c");
fs.normalize("/./a/d///..////b/c").should.be.eql("/a/b/c");
fs.normalize("/..").should.be.eql("/");
fs.normalize("/.").should.be.eql("/");
fs.normalize("/.git").should.be.eql("/.git");
fs.normalize("/a/b/c/.git").should.be.eql("/a/b/c/.git");
fs.normalize("/a/b/c/..git").should.be.eql("/a/b/c/..git");
fs.normalize("/a/b/c/..").should.be.eql("/a/b");
fs.normalize("/a/b/c/../..").should.be.eql("/a");
fs.normalize("/a/b/c/../../..").should.be.eql("/");
fs.normalize("C:\\a\\..").should.be.eql("C:\\");
fs.normalize("C:\\a\\b\\..").should.be.eql("C:\\a");
fs.normalize("C:\\a\\b\\\c\\..\\..").should.be.eql("C:\\a");
fs.normalize("C:\\a\\b\\d\\..\\c\\..\\..").should.be.eql("C:\\a");
fs.normalize("C:\\a\\b\\d\\\\.\\\\.\\c\\.\\..").should.be.eql("C:\\a\\b\\d");
});
});
describe("join", function() {
it("should join paths", function() {
var fs = new MemoryFileSystem();
fs.join("/", "a/b/c").should.be.eql("/a/b/c");
fs.join("/a", "b/c").should.be.eql("/a/b/c");
fs.join("/a/b", "c").should.be.eql("/a/b/c");
fs.join("/a/", "b/c").should.be.eql("/a/b/c");
fs.join("/a//", "b/c").should.be.eql("/a/b/c");
fs.join("a", "b/c").should.be.eql("a/b/c");
fs.join("a/b", "c").should.be.eql("a/b/c");
fs.join("C:", "a/b").should.be.eql("C:\\a\\b");
fs.join("C:\\", "a/b").should.be.eql("C:\\a\\b");
fs.join("C:\\", "a\\b").should.be.eql("C:\\a\\b");
});
it("should join paths (weird cases)", function() {
var fs = new MemoryFileSystem();
fs.join("/", "").should.be.eql("/");
fs.join("/a/b/", "").should.be.eql("/a/b/");
fs.join("/a/b/c", "").should.be.eql("/a/b/c");
fs.join("C:", "").should.be.eql("C:");
fs.join("C:\\a\\b", "").should.be.eql("C:\\a\\b");
});
it("should join paths (absolute request)", function() {
var fs = new MemoryFileSystem();
fs.join("/a/b/c", "/d/e/f").should.be.eql("/d/e/f");
fs.join("C:\\a\\b\\c", "/d/e/f").should.be.eql("/d/e/f");
fs.join("/a/b/c", "C:\\d\\e\\f").should.be.eql("C:\\d\\e\\f");
fs.join("C:\\a\\b\\c", "C:\\d\\e\\f").should.be.eql("C:\\d\\e\\f");
});
});
describe("os", function() {
var fileSystem;
beforeEach(function() {
fileSystem = new MemoryFileSystem({
"": true,
a: {
"": true,
index: new Buffer("1"), // /a/index
dir: {
"": true,
index: new Buffer("2") // /a/dir/index
}
},
"C:": {
"": true,
a: {
"": true,
index: new Buffer("3"), // C:\files\index
dir: {
"": true,
index: new Buffer("4") // C:\files\a\index
}
}
}
});
});
describe("unix", function() {
it("should stat stuff", function() {
fileSystem.statSync("/a").isDirectory().should.be.eql(true);
fileSystem.statSync("/a").isFile().should.be.eql(false);
fileSystem.statSync("/a/index").isDirectory().should.be.eql(false);
fileSystem.statSync("/a/index").isFile().should.be.eql(true);
fileSystem.statSync("/a/dir").isDirectory().should.be.eql(true);
fileSystem.statSync("/a/dir").isFile().should.be.eql(false);
fileSystem.statSync("/a/dir/index").isDirectory().should.be.eql(false);
fileSystem.statSync("/a/dir/index").isFile().should.be.eql(true);
});
it("should readdir directories", function() {
fileSystem.readdirSync("/a").should.be.eql(["index", "dir"]);
fileSystem.readdirSync("/a/dir").should.be.eql(["index"]);
});
it("should readdir directories", function() {
fileSystem.readFileSync("/a/index", "utf-8").should.be.eql("1");
fileSystem.readFileSync("/a/dir/index", "utf-8").should.be.eql("2");
});
it("should also accept multi slashs", function() {
fileSystem.statSync("/a///dir//index").isFile().should.be.eql(true);
});
});
describe("windows", function() {
it("should stat stuff", function() {
fileSystem.statSync("C:\\a").isDirectory().should.be.eql(true);
fileSystem.statSync("C:\\a").isFile().should.be.eql(false);
fileSystem.statSync("C:\\a\\index").isDirectory().should.be.eql(false);
fileSystem.statSync("C:\\a\\index").isFile().should.be.eql(true);
fileSystem.statSync("C:\\a\\dir").isDirectory().should.be.eql(true);
fileSystem.statSync("C:\\a\\dir").isFile().should.be.eql(false);
fileSystem.statSync("C:\\a\\dir\\index").isDirectory().should.be.eql(false);
fileSystem.statSync("C:\\a\\dir\\index").isFile().should.be.eql(true);
});
it("should readdir directories", function() {
fileSystem.readdirSync("C:\\a").should.be.eql(["index", "dir"]);
fileSystem.readdirSync("C:\\a\\dir").should.be.eql(["index"]);
});
it("should readdir directories", function() {
fileSystem.readFileSync("C:\\a\\index", "utf-8").should.be.eql("3");
fileSystem.readFileSync("C:\\a\\dir\\index", "utf-8").should.be.eql("4");
});
it("should also accept multi slashs", function() {
fileSystem.statSync("C:\\\\a\\\\\\dir\\\\index").isFile().should.be.eql(true);
});
it("should also accept a normal slash", function() {
fileSystem.statSync("C:\\a\\dir/index").isFile().should.be.eql(true);
fileSystem.statSync("C:\\a\\dir\\index").isFile().should.be.eql(true);
fileSystem.statSync("C:\\a/dir/index").isFile().should.be.eql(true);
fileSystem.statSync("C:\\a/dir\\index").isFile().should.be.eql(true);
});
});
});