Skip to content
This repository was archived by the owner on Aug 15, 2024. It is now read-only.

Commit 6666525

Browse files
authored
Merge branch 'master' into master
2 parents 322c951 + 7ae73eb commit 6666525

File tree

9 files changed

+123
-44
lines changed

9 files changed

+123
-44
lines changed

.eslintrc.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"es6": true
55
},
66
"parserOptions": {
7-
"sourceType": "module"
7+
"sourceType": "script"
88
},
99
"rules": {
1010
"accessor-pairs": "error",
@@ -74,10 +74,6 @@
7474
"id-blacklist": "error",
7575
"id-match": "error",
7676
"jsx-quotes": "error",
77-
"linebreak-style": [
78-
"error",
79-
"unix"
80-
],
8177
"lines-around-comment": "error",
8278
"lines-around-directive": "error",
8379
"max-depth": "error",

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ language: node_js
22
node_js:
33
- "4"
44
- "6"
5-
- "7"
5+
- "8"
66
script: npm run travis
77

88
before_install:

lib/MemoryFileSystem.js

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,18 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5+
56
"use strict";
67

78
const normalize = require("./normalize");
89
const join = require("./join");
10+
const MemoryFileSystemError = require("./MemoryFileSystemError");
911
const errors = require("errno");
1012
const stream = require("readable-stream");
1113

1214
const ReadableStream = stream.Readable;
1315
const WritableStream = stream.Writable;
1416

15-
class MemoryFileSystemError extends Error {
16-
constructor(err, path) {
17-
super(err, path);
18-
if (Error.captureStackTrace)
19-
Error.captureStackTrace(this, this.constructor)
20-
this.code = err.code;
21-
this.errno = err.errno;
22-
this.message = err.description;
23-
this.path = path;
24-
}
25-
}
26-
2717
function isDir(item) {
2818
if(typeof item !== "object") return false;
2919
return item[""] === true;
@@ -102,7 +92,7 @@ class MemoryFileSystem {
10292
isSocket: falseFn
10393
};
10494
} else {
105-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
95+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "stat");
10696
}
10797
}
10898

@@ -112,14 +102,14 @@ class MemoryFileSystem {
112102
let i = 0
113103
for(; i < path.length - 1; i++) {
114104
if(!isDir(current[path[i]]))
115-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
105+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "readFile");
116106
current = current[path[i]];
117107
}
118108
if(!isFile(current[path[i]])) {
119109
if(isDir(current[path[i]]))
120-
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
110+
throw new MemoryFileSystemError(errors.code.EISDIR, _path, "readFile");
121111
else
122-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
112+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "readFile");
123113
}
124114
current = current[path[i]];
125115
const encoding = typeof optionsOrEncoding === "object" ? optionsOrEncoding.encoding : optionsOrEncoding;
@@ -133,14 +123,14 @@ class MemoryFileSystem {
133123
let i = 0;
134124
for(; i < path.length - 1; i++) {
135125
if(!isDir(current[path[i]]))
136-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
126+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "readdir");
137127
current = current[path[i]];
138128
}
139129
if(!isDir(current[path[i]])) {
140130
if(isFile(current[path[i]]))
141-
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path);
131+
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path, "readdir");
142132
else
143-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
133+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "readdir");
144134
}
145135
return Object.keys(current[path[i]]).filter(Boolean);
146136
}
@@ -151,7 +141,7 @@ class MemoryFileSystem {
151141
let current = this.data;
152142
for(let i = 0; i < path.length; i++) {
153143
if(isFile(current[path[i]]))
154-
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path);
144+
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path, "mkdirp");
155145
else if(!isDir(current[path[i]]))
156146
current[path[i]] = {"":true};
157147
current = current[path[i]];
@@ -166,31 +156,32 @@ class MemoryFileSystem {
166156
let i = 0;
167157
for(; i < path.length - 1; i++) {
168158
if(!isDir(current[path[i]]))
169-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
159+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "mkdir");
170160
current = current[path[i]];
171161
}
172162
if(isDir(current[path[i]]))
173-
throw new MemoryFileSystemError(errors.code.EEXIST, _path);
163+
throw new MemoryFileSystemError(errors.code.EEXIST, _path, "mkdir");
174164
else if(isFile(current[path[i]]))
175-
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path);
165+
throw new MemoryFileSystemError(errors.code.ENOTDIR, _path, "mkdir");
176166
current[path[i]] = {"":true};
177167
return;
178168
}
179169

180170
_remove(_path, name, testFn) {
181171
const path = pathToArray(_path);
172+
const operation = name === "File" ? "unlink" : "rmdir";
182173
if(path.length === 0) {
183-
throw new MemoryFileSystemError(errors.code.EPERM, _path);
174+
throw new MemoryFileSystemError(errors.code.EPERM, _path, operation);
184175
}
185176
let current = this.data;
186177
let i = 0;
187178
for(; i < path.length - 1; i++) {
188179
if(!isDir(current[path[i]]))
189-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
180+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, operation);
190181
current = current[path[i]];
191182
}
192183
if(!testFn(current[path[i]]))
193-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
184+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, operation);
194185
delete current[path[i]];
195186
return;
196187
}
@@ -204,24 +195,24 @@ class MemoryFileSystem {
204195
}
205196

206197
readlinkSync(_path) {
207-
throw new MemoryFileSystemError(errors.code.ENOSYS, _path);
198+
throw new MemoryFileSystemError(errors.code.ENOSYS, _path, "readlink");
208199
}
209200

210201
writeFileSync(_path, content, optionsOrEncoding) {
211202
if(!content && !optionsOrEncoding) throw new Error("No content");
212203
const path = pathToArray(_path);
213204
if(path.length === 0) {
214-
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
205+
throw new MemoryFileSystemError(errors.code.EISDIR, _path, "writeFile");
215206
}
216207
let current = this.data;
217208
let i = 0
218209
for(; i < path.length - 1; i++) {
219210
if(!isDir(current[path[i]]))
220-
throw new MemoryFileSystemError(errors.code.ENOENT, _path);
211+
throw new MemoryFileSystemError(errors.code.ENOENT, _path, "writeFile");
221212
current = current[path[i]];
222213
}
223214
if(isDir(current[path[i]]))
224-
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
215+
throw new MemoryFileSystemError(errors.code.EISDIR, _path, "writeFile");
225216
const encoding = typeof optionsOrEncoding === "object" ? optionsOrEncoding.encoding : optionsOrEncoding;
226217
current[path[i]] = optionsOrEncoding || typeof content === "string" ? new Buffer(content, encoding) : content;
227218
return;

lib/MemoryFileSystemError.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
"use strict";
3+
4+
class MemoryFileSystemError extends Error {
5+
constructor(err, path, operation) {
6+
super(err, path);
7+
8+
// Set `name` and `message` before call `Error.captureStackTrace` \
9+
// so that we will obtain the correct 1st line of stack, like:
10+
// [Error]: [Message]
11+
this.name = this.constructor.name;
12+
var message = [`${err.code}:`, `${err.description},`];
13+
// Add operation name and path into message, similar to node `fs` style.
14+
if(operation) {
15+
message.push(operation);
16+
}
17+
message.push(`\'${path}\'`);
18+
this.message = message.join(' ');
19+
20+
this.code = err.code;
21+
this.errno = err.errno;
22+
this.path = path;
23+
this.operation = operation;
24+
25+
if(Error.captureStackTrace) {
26+
Error.captureStackTrace(this, this.constructor);
27+
}
28+
}
29+
}
30+
31+
module.exports = MemoryFileSystemError;

lib/join.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"use strict";
2+
13
const normalize = require("./normalize");
24

35
const absoluteWinRegExp = /^[A-Z]:([\\\/]|$)/i;

lib/normalize.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
"use strict";
2+
13
module.exports = function normalize(path) {
24
var parts = path.split(/(\\+|\/+)/);
35
if(parts.length === 1)
46
return path;
57
var result = [];
68
var absolutePathStart = 0;
7-
for(var i = 0, sep = false; i < parts.length; i++, sep = !sep) {
9+
for(var i = 0, sep = false; i < parts.length; i += 1, sep = !sep) {
810
var part = parts[i];
911
if(i === 0 && /^([A-Z]:)?$/i.test(part)) {
1012
result.push(part);
@@ -31,7 +33,7 @@ module.exports = function normalize(path) {
3133
// i. e. "/../b/c" => "/b/c"
3234
// i. e. "C:\..\a\b\c" => "C:\a\b\c"
3335
if (result[0] !== ".") {
34-
i++;
36+
i += 1;
3537
sep = !sep;
3638
result.length = absolutePathStart;
3739
} else {
@@ -47,7 +49,7 @@ module.exports = function normalize(path) {
4749
if(absolutePathStart === 0) {
4850
result.length -= 3;
4951
} else {
50-
i++;
52+
i += 1;
5153
sep = !sep;
5254
result.length = 2;
5355
}
@@ -71,9 +73,9 @@ module.exports = function normalize(path) {
7173
// i. e. "C:\." => "C:\"
7274
// i. e. "C:\.\a\b\c" => "C:\a\b\c"
7375
if(absolutePathStart === 0) {
74-
result.length--;
76+
result.length -= 1;
7577
} else {
76-
i++;
78+
i += 1;
7779
sep = !sep;
7880
}
7981
break;
@@ -83,7 +85,7 @@ module.exports = function normalize(path) {
8385
// i. e. "C:\a\." => "C:\"
8486
// i. e. "a/./b/c" => "a/b/c"
8587
// i. e. "/a/./b/c" => "/a/b/c"
86-
result.length--;
88+
result.length -= 1;
8789
break;
8890
}
8991
} else if(part) {
@@ -93,4 +95,4 @@ module.exports = function normalize(path) {
9395
if(result.length === 1 && /^[A-Za-z]:$/.test(result[0]))
9496
return result[0] + "\\";
9597
return result.join("");
96-
};
98+
};

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
],
1212
"scripts": {
1313
"test": "mocha",
14+
"lint": "eslint lib/*",
1415
"cover": "istanbul cover node_modules/mocha/bin/_mocha",
15-
"travis": "npm run cover -- --report lcovonly"
16+
"travis": "npm run cover -- --report lcovonly && npm run lint"
1617
},
1718
"engines": {
1819
"node": ">=4.3.0 <5.0.0 || >=5.10"
@@ -35,6 +36,7 @@
3536
"bl": "^1.0.0",
3637
"codecov.io": "^0.1.4",
3738
"coveralls": "^2.11.2",
39+
"eslint": "^4.0.0",
3840
"istanbul": "0.4.5",
3941
"mocha": "3.2.0",
4042
"should": "^4.0.4"

test/MemoryFileSystem.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ describe("pathToArray", function() {
374374
fs.pathToArray("C:\\a\\b").should.be.eql(["C:", "a", "b"]);
375375
});
376376
it("should fail on invalid paths", function() {
377+
var fs = new MemoryFileSystem();
377378
(function() {
378379
fs.pathToArray("0:/");
379380
}).should.throw();

test/MemoryFileSystemError.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
var bl = require("bl");
2+
var should = require("should");
3+
var MemoryFileSystem = require("../lib/MemoryFileSystem");
4+
var MemoryFileSystemError = require("../lib/MemoryFileSystemError");
5+
6+
describe("error", function() {
7+
function catchError(fn) {
8+
try {
9+
fn();
10+
} catch(e) {
11+
return e;
12+
}
13+
return null;
14+
}
15+
16+
it("should include the path in Error message", function(done) {
17+
var fs = new MemoryFileSystem();
18+
var invalidPath = "/nonexist/file";
19+
var error = catchError(function() {
20+
fs.statSync(invalidPath);
21+
});
22+
error.message.should.containEql(invalidPath);
23+
24+
fs.readFile(invalidPath, function(err) {
25+
err.message.should.containEql(invalidPath);
26+
done();
27+
});
28+
});
29+
it("should use correct error message in the first line of Error stack", function(done) {
30+
var fs = new MemoryFileSystem();
31+
fs.unlink("/test/abcd", function(error) {
32+
error.should.be.instanceof(Error);
33+
error.stack.should.startWith(error.name);
34+
35+
var firstLine = error.stack.split(/\r\n|\n/)[0];
36+
firstLine.should.containEql(error.code);
37+
firstLine.should.containEql(error.message);
38+
firstLine.should.containEql(error.operation);
39+
done();
40+
});
41+
});
42+
it("should work fine without operation name", function() {
43+
var errorData = {
44+
code:"ETEST",
45+
description:"testerror"
46+
};
47+
var errorPath = "file";
48+
var error = new MemoryFileSystemError(errorData, errorPath);
49+
error.message.should.startWith(error.code);
50+
error.stack.should.startWith(error.name);
51+
error.stack.should.containEql(error.message);
52+
error.stack.should.containEql(errorPath);
53+
});
54+
});

0 commit comments

Comments
 (0)