/
fake-fs.js
125 lines (105 loc) · 2.89 KB
/
fake-fs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
var stat = require('./stat')
var normalize = require('path').normalize
var join = require('path').join
function FsError (code) {
var err = new Error(code)
err.code = code
return err
}
module.exports = Fs
function Fs (paths) {
this.root = new stat.Dir
}
Fs.prototype.dir = function (path, opts) {
return this._add(path, new stat.Dir(opts))
}
Fs.prototype.file = function (path, content, encoding) {
return this._add(path, new stat.File(content, encoding))
}
Fs.prototype.at = function (path) {
return {
_fs: this,
dir: function (p) {
p = join(path, p).replace('\\', '/')
this._fs.dir.apply(this._fs, arguments)
return this
},
file: function (p) {
p = join(path, p).replace('\\', '/')
this._fs.file.apply(this._fs, arguments)
return this
}
}
}
Fs.prototype._add = function (path, item) {
var segs = path.split('/')
var dir = this.root
for (var i = 0; i < segs.length - 1; i++) {
dir = dir.childs[segs[i]] || (dir.childs[segs[i]] = new stat.Dir)
if (!dir.isDirectory()) {
throw new Error('There is already ' + dir + ' defined at ' + segs.slice(i).join('/'))
}
}
dir.childs[segs[i]] = item
return this
}
Fs.prototype._itemAt = function (path) {
path = normalize(path).replace('\\', '/') // windows support
var segs = path.split('/')
var item = this.root
if (segs[0] == '.') return item
for (var i = 0; i < segs.length; i++) {
item = item.childs && item.childs[segs[i]]
if (!item) return
}
return item
}
Fs.prototype._get = function (path) {
var item = this._itemAt(path)
if (!item) throw FsError('ENOENT')
return item
}
Fs.prototype.statSync = function (path) {
return this._get(path)
}
Fs.prototype.existsSync = function (path) {
return !!this._itemAt(path)
}
Fs.prototype.readdirSync = function (dir) {
var item = this._get(dir)
if (!item.isDirectory()) throw FsError('ENOTDIR')
return Object.keys(item.childs)
}
Fs.prototype.readFileSync = function (filename, encoding) {
var item = this._get(filename)
if (item.isDirectory()) throw FsError('EISDIR')
return item.read(encoding)
}
;['readdir', 'stat'].forEach(function (meth) {
var sync = meth + 'Sync'
Fs.prototype[meth] = function (p, cb) {
var res, err
try {
res = this[sync].call(this, p)
} catch (e) {
err = e
}
cb && cb(err, res)
}
})
Fs.prototype.readFile = function (filename, encoding, cb) {
if (typeof encoding != 'string') {
cb = encoding
encoding = undefined
}
var res, err
try {
res = this.readFileSync(filename, encoding)
} catch (e) {
err = e
}
cb && cb(err, res)
}
Fs.prototype.exists = function (path, cb) {
cb && cb(this.existsSync(path))
}