UNPKG

4.4 kBJavaScriptView Raw
1var path = require('path');
2
3var Directory = require('./directory').Directory;
4var File = require('./file').File;
5
6
7var isWindows = process.platform === 'win32';
8
9function getPathParts(filepath) {
10 var parts = path._makeLong(path.resolve(filepath)).split(path.sep);
11 parts.shift();
12 if (isWindows) {
13 parts.shift();
14 }
15 return parts;
16}
17
18
19
20/**
21 * Create a new file system.
22 * @constructor
23 */
24function FileSystem() {
25
26 /**
27 * Root directory.
28 * @type {Directory}
29 */
30 this._root = new Directory('');
31
32}
33
34
35/**
36 * Get a file system item.
37 * @param {string} filepath Path to item.
38 * @return {Item} The item (or null if not found).
39 */
40FileSystem.prototype.getItem = function(filepath) {
41 var parts = getPathParts(filepath);
42 var item = this._root;
43 for (var i = 0, ii = parts.length; i < ii; ++i) {
44 item = item.getItem(parts[i]);
45 if (!item) {
46 break;
47 }
48 }
49 return item;
50};
51
52
53/**
54 * Populate a directory with an item.
55 * @param {Directory} directory The directory to populate.
56 * @param {string} name The name of the item.
57 * @param {string|Buffer|function|Object} obj Instructions for creating the
58 * item.
59 */
60function populate(directory, name, obj) {
61 var item;
62 if (typeof obj === 'string' || Buffer.isBuffer(obj)) {
63 // contents for a file
64 item = new File(name);
65 item.setContent(obj);
66 } else if (typeof obj === 'function') {
67 // item factory
68 item = obj(name);
69 } else {
70 // directory with more to populate
71 item = new Directory(name);
72 for (var key in obj) {
73 populate(item, key, obj[key]);
74 }
75 }
76 directory.addItem(item);
77}
78
79
80/**
81 * Configure a mock file system.
82 * @param {Object} paths Config object.
83 * @return {FileSystem} Mock file system.
84 */
85FileSystem.create = function(paths) {
86 var system = new FileSystem();
87
88 for (var filepath in paths) {
89 var parts = getPathParts(filepath);
90 var directory = system._root;
91 var i, ii, name, candidate;
92 for (i = 0, ii = parts.length - 1; i < ii; ++i) {
93 name = parts[i];
94 candidate = directory.getItem(name);
95 if (!candidate) {
96 directory = directory.addItem(new Directory(name));
97 } else if (candidate instanceof Directory) {
98 directory = candidate;
99 } else {
100 throw new Error('Failed to create directory: ' + filepath);
101 }
102 }
103 populate(directory, parts[i], paths[filepath]);
104 }
105
106 return system;
107};
108
109
110/**
111 * Generate a factory for new files.
112 * @param {Object} config File config.
113 * @return {function(string):File} Factory that creates a new file given a name.
114 */
115FileSystem.file = function(config) {
116 config = config || {};
117 return function(name) {
118 var file = new File(name);
119 if (config.hasOwnProperty('content')) {
120 file.setContent(config.content);
121 }
122 if (config.hasOwnProperty('mode')) {
123 file.setMode(config.mode);
124 } else {
125 file.setMode(0666);
126 }
127 if (config.hasOwnProperty('atime')) {
128 file.setATime(config.atime);
129 }
130 if (config.hasOwnProperty('ctime')) {
131 file.setCTime(config.ctime);
132 }
133 if (config.hasOwnProperty('mtime')) {
134 file.setMTime(config.mtime);
135 }
136 if (config.hasOwnProperty('uid')) {
137 file.setUid(config.uid);
138 }
139 if (config.hasOwnProperty('gid')) {
140 file.setGid(config.gid);
141 }
142 return file;
143 };
144};
145
146
147/**
148 * Generate a factory for new directories.
149 * @param {Object} config File config.
150 * @return {function(string):Directory} Factory that creates a new directory
151 * given a name.
152 */
153FileSystem.directory = function(config) {
154 config = config || {};
155 return function(name) {
156 var dir = new Directory(name);
157 if (config.hasOwnProperty('mode')) {
158 dir.setMode(config.mode);
159 } else {
160 dir.setMode(0777);
161 }
162 if (config.hasOwnProperty('atime')) {
163 dir.setATime(config.atime);
164 }
165 if (config.hasOwnProperty('ctime')) {
166 dir.setCTime(config.ctime);
167 }
168 if (config.hasOwnProperty('mtime')) {
169 dir.setMTime(config.mtime);
170 }
171 if (config.hasOwnProperty('uid')) {
172 dir.setUid(config.uid);
173 }
174 if (config.hasOwnProperty('gid')) {
175 dir.setGid(config.gid);
176 }
177 if (config.hasOwnProperty('items')) {
178 for (name in config.items) {
179 populate(dir, name, config.items[name]);
180 }
181 }
182 return dir;
183 };
184};
185
186
187/**
188 * Module exports.
189 * @type {function}
190 */
191module.exports = FileSystem;