pax_global_header00006660000000000000000000000064130220074200014500gustar00rootroot0000000000000052 comment=1b3c3572b47caa8b6d49b938456cfe180834f377 memory-fs-0.4.1/000077500000000000000000000000001302200742000134205ustar00rootroot00000000000000memory-fs-0.4.1/.gitattributes000066400000000000000000000007431302200742000163170ustar00rootroot00000000000000# 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 memory-fs-0.4.1/.gitignore000066400000000000000000000021011302200742000154020ustar00rootroot00000000000000# 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 *.msp memory-fs-0.4.1/.travis.yml000066400000000000000000000005371302200742000155360ustar00rootroot00000000000000language: 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 memory-fs-0.4.1/README.md000066400000000000000000000013651302200742000147040ustar00rootroot00000000000000# 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 variants 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) memory-fs-0.4.1/lib/000077500000000000000000000000001302200742000141665ustar00rootroot00000000000000memory-fs-0.4.1/lib/MemoryFileSystem.js000066400000000000000000000205261302200742000200060ustar00rootroot00000000000000/* 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; 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.pathToArray = pathToArray; 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", "rmdir", "unlink", "readlink"].forEach(function(fn) { MemoryFileSystem.prototype[fn] = function(path, callback) { try { var result = this[fn + "Sync"](path); } catch(e) { setImmediate(function() { callback(e); }); return; } setImmediate(function() { callback(null, result); }); }; }); ["mkdir", "readFile"].forEach(function(fn) { MemoryFileSystem.prototype[fn] = function(path, optArg, callback) { if(!callback) { callback = optArg; optArg = undefined; } try { var result = this[fn + "Sync"](path, optArg); } catch(e) { setImmediate(function() { callback(e); }); return; } setImmediate(function() { callback(null, result); }); }; }); MemoryFileSystem.prototype.exists = function(path, callback) { return callback(this.existsSync(path)); } 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(); }; memory-fs-0.4.1/lib/join.js000066400000000000000000000012011302200742000154550ustar00rootroot00000000000000var 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.replace(/\//g, "\\") + "\\" + request.replace(/\//g, "\\")); if(absoluteNixRegExp.test(path)) return normalize(path + "/" + request); return normalize(path + "/" + request); }; memory-fs-0.4.1/lib/normalize.js000066400000000000000000000040071302200742000165250ustar00rootroot00000000000000module.exports = function normalize(path) { var parts = path.split(/(\\+|\/+)/); if(parts.length === 1) return path; var result = []; var absolutePathStart = 0; for(var i = 0, sep = false; i < parts.length; i++, sep = !sep) { var part = parts[i]; if(i === 0 && /^([A-Z]:)?$/i.test(part)) { result.push(part); absolutePathStart = 2; } else if(sep) { result.push(part[0]); } else if(part === "..") { switch(result.length) { case 0: // i. e. ".." => ".." // i. e. "../a/b/c" => "../a/b/c" result.push(part); break; case 2: // i. e. "a/.." => "" // i. e. "/.." => "/" // i. e. "C:\.." => "C:\" // i. e. "a/../b/c" => "b/c" // i. e. "/../b/c" => "/b/c" // i. e. "C:\..\a\b\c" => "C:\a\b\c" i++; sep = !sep; result.length = absolutePathStart; break; case 4: // i. e. "a/b/.." => "a" // i. e. "/a/.." => "/" // i. e. "C:\a\.." => "C:\" // i. e. "/a/../b/c" => "/b/c" if(absolutePathStart === 0) { result.length -= 3; } else { i++; sep = !sep; result.length = 2; } break; default: // i. e. "/a/b/.." => "/a" // i. e. "/a/b/../c" => "/a/c" result.length -= 3; break; } } else if(part === ".") { switch(result.length) { case 0: // i. e. "." => "." // i. e. "./a/b/c" => "./a/b/c" result.push(part); break; case 2: // i. e. "a/." => "a" // i. e. "/." => "/" // i. e. "C:\." => "C:\" // i. e. "C:\.\a\b\c" => "C:\a\b\c" if(absolutePathStart === 0) { result.length--; } else { i++; sep = !sep; } break; default: // i. e. "a/b/." => "a/b" // i. e. "/a/." => "/" // i. e. "C:\a\." => "C:\" // i. e. "a/./b/c" => "a/b/c" // i. e. "/a/./b/c" => "/a/b/c" result.length--; break; } } else if(part) { result.push(part); } } if(result.length === 1 && /^[A-Za-z]:$/.test(result)) return result[0] + "\\"; return result.join(""); }; memory-fs-0.4.1/package.json000066400000000000000000000017231302200742000157110ustar00rootroot00000000000000{ "name": "memory-fs", "version": "0.4.1", "description": "A simple in-memory filesystem. Holds data in a javascript object.", "main": "lib/MemoryFileSystem.js", "directories": { "test": "test" }, "files": [ "lib/" ], "scripts": { "test": "mocha", "cover": "istanbul cover node_modules/mocha/bin/_mocha", "travis": "npm run cover -- --report lcovonly" }, "repository": { "type": "git", "url": "https://github.com/webpack/memory-fs.git" }, "keywords": [ "fs", "memory" ], "author": "Tobias Koppers @sokra", "license": "MIT", "bugs": { "url": "https://github.com/webpack/memory-fs/issues" }, "homepage": "https://github.com/webpack/memory-fs", "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" }, "dependencies": { "errno": "^0.1.3", "readable-stream": "^2.0.1" } } memory-fs-0.4.1/test/000077500000000000000000000000001302200742000143775ustar00rootroot00000000000000memory-fs-0.4.1/test/MemoryFileSystem.js000066400000000000000000000376101302200742000202210ustar00rootroot00000000000000var 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"]); }); it("should call a mkdir callback when passed as the third argument", function(done) { var fs = new MemoryFileSystem(); fs.mkdir('/test', {}, function(err) { if (err) throw err; done(); }); }); }); 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() { ["stat", "readdir", "mkdirp", "rmdir", "unlink", "readlink"].forEach(function(methodName) { it("should call " + methodName + " callback in a new event cycle", function(done) { var fs = new MemoryFileSystem(); var isCalled = false; fs[methodName]('/test', function() { isCalled = true; done(); }); should(isCalled).eql(false); }); }); ["mkdir", "readFile"].forEach(function(methodName) { it("should call " + methodName + " a callback in a new event cycle", function(done) { var fs = new MemoryFileSystem(); var isCalled = false; fs[methodName]('/test', {}, function() { isCalled = true; done(); }); should(isCalled).eql(false); }); }); 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("pathToArray", function() { it("should split path to an array of parts", function() { var fs = new MemoryFileSystem(); fs.pathToArray("/a/b/c").should.be.eql(["a", "b", "c"]); fs.pathToArray("C:/a/b").should.be.eql(["C:", "a", "b"]); fs.pathToArray("C:\\a\\b").should.be.eql(["C:", "a", "b"]); }); it("should fail on invalid paths", function() { (function() { fs.pathToArray("0:/"); }).should.throw(); }); }); 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"); fs.join("C:/a/b", "./../c/d").should.be.eql("C:\\a\\c\\d"); fs.join("C:\\a\\b", "./../c/d").should.be.eql("C:\\a\\c\\d"); }); it("should join paths (weird cases)", function() { var fs = new MemoryFileSystem(); fs.join("/", "").should.be.eql("/"); // https://github.com/webpack/memory-fs/pull/17 fs.join("/", undefined).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); }); }); });