UNPKG

5.51 kBJavaScriptView Raw
1(function (require, exports) {
2
3var Q = require("qq");
4var BOOT = require("fs-boot");
5var FS = require("./q-fs");
6var COMMON = require("./common");
7
8var Fs = exports.Fs = function (files) {
9 var fs = Object.create(BOOT);
10 var root = {};
11 var now = new Date();
12
13 function init() {
14 // construct a file tree
15 Object.keys(files).forEach(function (path) {
16 var content = files[path];
17 find(root, path).set(content);
18 });
19 }
20
21 function find(at, path) {
22 path = fs.absolute(path);
23 if (path === "" || path === FS.ROOT) {
24 return Node(function get() {
25 return root;
26 }, function set(content) {
27 root = content;
28 });
29 }
30 var parts = FS.split(path);
31 var empty = parts.shift();
32 if (empty !== "")
33 throw new Error("assertion: first component of root should be empty");
34 var i, ii;
35 var manifest = function () {};
36 for (i = 0, ii = parts.length - 1; i < ii; i++) {
37 var part = parts[i];
38 if (part === ".") {
39 continue;
40 } if (typeof at[part] !== "object") {
41 manifest = (function (on, part, manifest) {
42 var created = {};
43 at = created;
44 return function () {
45 on[part] = created;
46 manifest();
47 };
48 })(at, part, manifest);
49 } else {
50 at = at[part];
51 }
52 }
53 var leaf = parts[i];
54 return Node(function get() {
55 return at[leaf];
56 }, function set(content) {
57 manifest();
58 at[leaf] = content;
59 });
60 }
61
62 fs.list = function (path) {
63 path = String(path);
64 return Q.when(fs.stat(path), function (stat) {
65 if (!stat.isDirectory())
66 throw new Error("Can't list non-directory " + path);
67 var node = find(root, path).get();
68 return Object.keys(node);
69 });
70 };
71
72 fs.open = function (path, flags, charset, options) {
73 if (typeof flags == "object") {
74 options = flags;
75 flags = options.flags;
76 charset = options.charset;
77 } else {
78 options = options || {};
79 }
80 var node = find(root, path);
81 // TODO create an actual open file object, rather
82 // than this rather primitive duck
83 flags = flags || "r";
84 var binary = flags.indexOf("b") >= 0;
85 charset = charset || "utf-8";
86 var stat = fs.stat(path);
87 var isFile = Q.post(stat, 'isFile');
88 return Q.when(isFile, function (isFile) {
89 if (!isFile) {
90 throw new Error("Can't open non-file " + path);
91 }
92 return {
93 "read": function () {
94 var content = node.get();
95 if (!binary)
96 content = content.toString(charset);
97 return content;
98 }
99 };
100 });
101 };
102
103 fs.stat = function (path) {
104 var stat = find(root, path);
105 if (stat.get() === undefined)
106 return Q.reject("No such file: " + path);
107 return stat;
108 };
109
110 fs.getNode = function (path) {
111 path = path || "";
112 return find(root, path).get();
113 };
114
115 fs.canonical = function (path) {
116 return fs.normal(path);
117 };
118
119 var Node = function (get, set) {
120 var self = Object.create(Node.prototype);
121 self.get = get;
122 self.set = set;
123 return self;
124 };
125
126 Node.prototype = Object.create(GenericNode.prototype);
127
128 Node.prototype.constructor = Node;
129
130 Node.prototype.lastModified = function () {
131 return now;
132 };
133
134 COMMON.update(fs, function () {
135 return fs.ROOT;
136 });
137
138 init();
139
140 return fs;
141};
142
143var GenericNode = function () {};
144
145GenericNode.prototype.exists = function () {
146 var node = this.get();
147 return typeof node !== "undefined";
148};
149
150GenericNode.prototype.isFile = function () {
151 var node = this.get();
152 return typeof node !== "undefined" && (
153 typeof node !== "object" ||
154 node.constructor !== Object
155 );
156};
157
158GenericNode.prototype.isDirectory = function () {
159 var node = this.get();
160 return (
161 typeof node === "object" &&
162 node.constructor === Object
163 )
164};
165
166exports.mock = function (fs, root) {
167 return Q.when(fs.listTree(root), function (list) {
168 var tree = {};
169 var done;
170 list.forEach(function (path) {
171 var actual = fs.join(root, path);
172 var relative = fs.relativeFromDirectory(root, actual);
173 var partial = Q.when(fs.stat(actual), function (stat) {
174 if (stat.isFile()) {
175 tree[relative] = fs.read(path, "rb");
176 }
177 });
178 done = Q.when(done, function () {
179 return partial;
180 });
181 });
182 return Q.when(done, function () {
183 return Q.when(Q.shallow(tree), Fs);
184 });
185 });
186};
187
188}).apply(null, typeof exports !== "undefined" ?
189 [require, exports] :
190 [
191 function (id) {
192 id = id.toUpperCase()
193 .replace(".", "Q_FS")
194 .replace("/", "$")
195 .replace("-", "_");
196 return window[id];
197 },
198 Q_FS$MOCK
199 ]
200)