|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 const { pathFor, platform } = require("sdk/system"); |
|
8 const fs = require("sdk/io/fs"); |
|
9 const url = require("sdk/url"); |
|
10 const path = require("sdk/fs/path"); |
|
11 const { defer } = require("sdk/core/promise"); |
|
12 const { Buffer } = require("sdk/io/buffer"); |
|
13 const { is } = require("sdk/system/xul-app"); |
|
14 |
|
15 // Use profile directory to list / read / write files. |
|
16 const profilePath = pathFor("ProfD"); |
|
17 const fileNameInProfile = "compatibility.ini"; |
|
18 const dirNameInProfile = "extensions"; |
|
19 const filePathInProfile = path.join(profilePath, fileNameInProfile); |
|
20 const dirPathInProfile = path.join(profilePath, dirNameInProfile); |
|
21 const mkdirPath = path.join(profilePath, "sdk-fixture-mkdir"); |
|
22 const writePath = path.join(profilePath, "sdk-fixture-writeFile"); |
|
23 const unlinkPath = path.join(profilePath, "sdk-fixture-unlink"); |
|
24 const truncatePath = path.join(profilePath, "sdk-fixture-truncate"); |
|
25 const renameFromPath = path.join(profilePath, "sdk-fixture-rename-from"); |
|
26 const renameToPath = path.join(profilePath, "sdk-fixture-rename-to"); |
|
27 const chmodPath = path.join(profilePath, "sdk-fixture-chmod"); |
|
28 |
|
29 const profileEntries = [ |
|
30 "compatibility.ini", |
|
31 "extensions", |
|
32 "prefs.js" |
|
33 // There are likely to be a lot more files but we can"t really |
|
34 // on consistent list so we limit to this. |
|
35 ]; |
|
36 |
|
37 const isWindows = platform.indexOf('win') === 0; |
|
38 |
|
39 exports["test readdir"] = function(assert, end) { |
|
40 var async = false; |
|
41 fs.readdir(profilePath, function(error, entries) { |
|
42 assert.ok(async, "readdir is async"); |
|
43 assert.ok(!error, "there is no error when reading directory"); |
|
44 assert.ok(profileEntries.length <= entries.length, |
|
45 "got at least number of entries we expect"); |
|
46 assert.ok(profileEntries.every(function(entry) { |
|
47 return entries.indexOf(entry) >= 0; |
|
48 }), "all profiles are present"); |
|
49 end(); |
|
50 }); |
|
51 |
|
52 async = true; |
|
53 }; |
|
54 |
|
55 exports["test readdir error"] = function(assert, end) { |
|
56 var async = false; |
|
57 var path = profilePath + "-does-not-exists"; |
|
58 fs.readdir(path, function(error, entries) { |
|
59 assert.ok(async, "readdir is async"); |
|
60 assert.equal(error.message, "ENOENT, readdir " + path); |
|
61 assert.equal(error.code, "ENOENT", "error has a code"); |
|
62 assert.equal(error.path, path, "error has a path"); |
|
63 assert.equal(error.errno, 34, "error has a errno"); |
|
64 end(); |
|
65 }); |
|
66 |
|
67 async = true; |
|
68 }; |
|
69 |
|
70 exports["test readdirSync"] = function(assert) { |
|
71 var async = false; |
|
72 var entries = fs.readdirSync(profilePath); |
|
73 assert.ok(profileEntries.length <= entries.length, |
|
74 "got at least number of entries we expect"); |
|
75 assert.ok(profileEntries.every(function(entry) { |
|
76 return entries.indexOf(entry) >= 0; |
|
77 }), "all profiles are present"); |
|
78 }; |
|
79 |
|
80 exports["test readdirSync error"] = function(assert) { |
|
81 var async = false; |
|
82 var path = profilePath + "-does-not-exists"; |
|
83 try { |
|
84 fs.readdirSync(path); |
|
85 assert.fail(Error("No error was thrown")); |
|
86 } catch (error) { |
|
87 assert.equal(error.message, "ENOENT, readdir " + path); |
|
88 assert.equal(error.code, "ENOENT", "error has a code"); |
|
89 assert.equal(error.path, path, "error has a path"); |
|
90 assert.equal(error.errno, 34, "error has a errno"); |
|
91 } |
|
92 }; |
|
93 |
|
94 exports["test readFile"] = function(assert, end) { |
|
95 let async = false; |
|
96 fs.readFile(filePathInProfile, function(error, content) { |
|
97 assert.ok(async, "readFile is async"); |
|
98 assert.ok(!error, "error is falsy"); |
|
99 |
|
100 assert.ok(Buffer.isBuffer(content), "readFile returns buffer"); |
|
101 assert.ok(typeof(content.length) === "number", "buffer has length"); |
|
102 assert.ok(content.toString().indexOf("[Compatibility]") >= 0, |
|
103 "content contains expected data"); |
|
104 end(); |
|
105 }); |
|
106 async = true; |
|
107 }; |
|
108 |
|
109 exports["test readFile error"] = function(assert, end) { |
|
110 let async = false; |
|
111 let path = filePathInProfile + "-does-not-exists"; |
|
112 fs.readFile(path, function(error, content) { |
|
113 assert.ok(async, "readFile is async"); |
|
114 assert.equal(error.message, "ENOENT, open " + path); |
|
115 assert.equal(error.code, "ENOENT", "error has a code"); |
|
116 assert.equal(error.path, path, "error has a path"); |
|
117 assert.equal(error.errno, 34, "error has a errno"); |
|
118 |
|
119 end(); |
|
120 }); |
|
121 async = true; |
|
122 }; |
|
123 |
|
124 exports["test readFileSync not implemented"] = function(assert) { |
|
125 let buffer = fs.readFileSync(filePathInProfile); |
|
126 assert.ok(buffer.toString().indexOf("[Compatibility]") >= 0, |
|
127 "read content"); |
|
128 }; |
|
129 |
|
130 exports["test fs.stat file"] = function(assert, end) { |
|
131 let async = false; |
|
132 let path = filePathInProfile; |
|
133 fs.stat(path, function(error, stat) { |
|
134 assert.ok(async, "fs.stat is async"); |
|
135 assert.ok(!error, "error is falsy"); |
|
136 assert.ok(!stat.isDirectory(), "not a dir"); |
|
137 assert.ok(stat.isFile(), "is a file"); |
|
138 assert.ok(!stat.isSymbolicLink(), "isn't a symlink"); |
|
139 assert.ok(typeof(stat.size) === "number", "size is a number"); |
|
140 assert.ok(stat.exists === true, "file exists"); |
|
141 assert.ok(typeof(stat.isBlockDevice()) === "boolean"); |
|
142 assert.ok(typeof(stat.isCharacterDevice()) === "boolean"); |
|
143 assert.ok(typeof(stat.isFIFO()) === "boolean"); |
|
144 assert.ok(typeof(stat.isSocket()) === "boolean"); |
|
145 assert.ok(typeof(stat.hidden) === "boolean"); |
|
146 assert.ok(typeof(stat.writable) === "boolean") |
|
147 assert.ok(stat.readable === true); |
|
148 |
|
149 end(); |
|
150 }); |
|
151 async = true; |
|
152 }; |
|
153 |
|
154 exports["test fs.stat dir"] = function(assert, end) { |
|
155 let async = false; |
|
156 let path = dirPathInProfile; |
|
157 fs.stat(path, function(error, stat) { |
|
158 assert.ok(async, "fs.stat is async"); |
|
159 assert.ok(!error, "error is falsy"); |
|
160 assert.ok(stat.isDirectory(), "is a dir"); |
|
161 assert.ok(!stat.isFile(), "not a file"); |
|
162 assert.ok(!stat.isSymbolicLink(), "isn't a symlink"); |
|
163 assert.ok(typeof(stat.size) === "number", "size is a number"); |
|
164 assert.ok(stat.exists === true, "file exists"); |
|
165 assert.ok(typeof(stat.isBlockDevice()) === "boolean"); |
|
166 assert.ok(typeof(stat.isCharacterDevice()) === "boolean"); |
|
167 assert.ok(typeof(stat.isFIFO()) === "boolean"); |
|
168 assert.ok(typeof(stat.isSocket()) === "boolean"); |
|
169 assert.ok(typeof(stat.hidden) === "boolean"); |
|
170 assert.ok(typeof(stat.writable) === "boolean") |
|
171 assert.ok(typeof(stat.readable) === "boolean"); |
|
172 |
|
173 end(); |
|
174 }); |
|
175 async = true; |
|
176 }; |
|
177 |
|
178 exports["test fs.stat error"] = function(assert, end) { |
|
179 let async = false; |
|
180 let path = filePathInProfile + "-does-not-exists"; |
|
181 fs.stat(path, function(error, stat) { |
|
182 assert.ok(async, "fs.stat is async"); |
|
183 assert.equal(error.message, "ENOENT, stat " + path); |
|
184 assert.equal(error.code, "ENOENT", "error has a code"); |
|
185 assert.equal(error.path, path, "error has a path"); |
|
186 assert.equal(error.errno, 34, "error has a errno"); |
|
187 |
|
188 end(); |
|
189 }); |
|
190 async = true; |
|
191 }; |
|
192 |
|
193 exports["test fs.exists NO"] = function(assert, end) { |
|
194 let async = false |
|
195 let path = filePathInProfile + "-does-not-exists"; |
|
196 fs.exists(path, function(error, value) { |
|
197 assert.ok(async, "fs.exists is async"); |
|
198 assert.ok(!error, "error is falsy"); |
|
199 assert.ok(!value, "file does not exists"); |
|
200 end(); |
|
201 }); |
|
202 async = true; |
|
203 }; |
|
204 |
|
205 exports["test fs.exists YES"] = function(assert, end) { |
|
206 let async = false |
|
207 let path = filePathInProfile |
|
208 fs.exists(path, function(error, value) { |
|
209 assert.ok(async, "fs.exists is async"); |
|
210 assert.ok(!error, "error is falsy"); |
|
211 assert.ok(value, "file exists"); |
|
212 end(); |
|
213 }); |
|
214 async = true; |
|
215 }; |
|
216 |
|
217 exports["test fs.exists NO"] = function(assert, end) { |
|
218 let async = false |
|
219 let path = filePathInProfile + "-does-not-exists"; |
|
220 fs.exists(path, function(error, value) { |
|
221 assert.ok(async, "fs.exists is async"); |
|
222 assert.ok(!error, "error is falsy"); |
|
223 assert.ok(!value, "file does not exists"); |
|
224 end(); |
|
225 }); |
|
226 async = true; |
|
227 }; |
|
228 |
|
229 exports["test fs.existsSync"] = function(assert) { |
|
230 let path = filePathInProfile |
|
231 assert.equal(fs.existsSync(path), true, "exists"); |
|
232 assert.equal(fs.existsSync(path + "-does-not-exists"), false, "exists"); |
|
233 }; |
|
234 |
|
235 exports["test fs.mkdirSync fs.rmdirSync"] = function(assert) { |
|
236 let path = mkdirPath; |
|
237 |
|
238 assert.equal(fs.existsSync(path), false, "does not exists"); |
|
239 fs.mkdirSync(path); |
|
240 assert.equal(fs.existsSync(path), true, "dir was created"); |
|
241 try { |
|
242 fs.mkdirSync(path); |
|
243 assert.fail(Error("mkdir on existing should throw")); |
|
244 } catch (error) { |
|
245 assert.equal(error.message, "EEXIST, mkdir " + path); |
|
246 assert.equal(error.code, "EEXIST", "error has a code"); |
|
247 assert.equal(error.path, path, "error has a path"); |
|
248 assert.equal(error.errno, 47, "error has a errno"); |
|
249 } |
|
250 fs.rmdirSync(path); |
|
251 assert.equal(fs.existsSync(path), false, "dir was removed"); |
|
252 }; |
|
253 |
|
254 exports["test fs.mkdir"] = function(assert, end) { |
|
255 let path = mkdirPath; |
|
256 |
|
257 if (!fs.existsSync(path)) { |
|
258 let async = false; |
|
259 fs.mkdir(path, function(error) { |
|
260 assert.ok(async, "mkdir is async"); |
|
261 assert.ok(!error, "no error"); |
|
262 assert.equal(fs.existsSync(path), true, "dir was created"); |
|
263 fs.rmdirSync(path); |
|
264 assert.equal(fs.existsSync(path), false, "dir was removed"); |
|
265 end(); |
|
266 }); |
|
267 async = true; |
|
268 } |
|
269 }; |
|
270 |
|
271 exports["test fs.mkdir error"] = function(assert, end) { |
|
272 let path = mkdirPath; |
|
273 |
|
274 if (!fs.existsSync(path)) { |
|
275 fs.mkdirSync(path); |
|
276 let async = false; |
|
277 fs.mkdir(path, function(error) { |
|
278 assert.ok(async, "mkdir is async"); |
|
279 assert.equal(error.message, "EEXIST, mkdir " + path); |
|
280 assert.equal(error.code, "EEXIST", "error has a code"); |
|
281 assert.equal(error.path, path, "error has a path"); |
|
282 assert.equal(error.errno, 47, "error has a errno"); |
|
283 fs.rmdirSync(path); |
|
284 assert.equal(fs.existsSync(path), false, "dir was removed"); |
|
285 end(); |
|
286 }); |
|
287 async = true; |
|
288 } |
|
289 }; |
|
290 |
|
291 exports["test fs.rmdir"] = function(assert, end) { |
|
292 let path = mkdirPath; |
|
293 |
|
294 if (!fs.existsSync(path)) { |
|
295 fs.mkdirSync(path); |
|
296 assert.equal(fs.existsSync(path), true, "dir exists"); |
|
297 let async = false; |
|
298 fs.rmdir(path, function(error) { |
|
299 assert.ok(async, "mkdir is async"); |
|
300 assert.ok(!error, "no error"); |
|
301 assert.equal(fs.existsSync(path), false, "dir was removed"); |
|
302 end(); |
|
303 }); |
|
304 async = true; |
|
305 } |
|
306 }; |
|
307 |
|
308 |
|
309 exports["test fs.rmdir error"] = function(assert, end) { |
|
310 let path = mkdirPath; |
|
311 |
|
312 if (!fs.existsSync(path)) { |
|
313 assert.equal(fs.existsSync(path), false, "dir doesn't exists"); |
|
314 let async = false; |
|
315 fs.rmdir(path, function(error) { |
|
316 assert.ok(async, "mkdir is async"); |
|
317 assert.equal(error.message, "ENOENT, remove " + path); |
|
318 assert.equal(error.code, "ENOENT", "error has a code"); |
|
319 assert.equal(error.path, path, "error has a path"); |
|
320 assert.equal(error.errno, 34, "error has a errno"); |
|
321 assert.equal(fs.existsSync(path), false, "dir is removed"); |
|
322 end(); |
|
323 }); |
|
324 async = true; |
|
325 } |
|
326 }; |
|
327 |
|
328 exports["test fs.truncateSync fs.unlinkSync"] = function(assert) { |
|
329 let path = truncatePath; |
|
330 |
|
331 assert.equal(fs.existsSync(path), false, "does not exists"); |
|
332 fs.truncateSync(path); |
|
333 assert.equal(fs.existsSync(path), true, "file was created"); |
|
334 fs.truncateSync(path); |
|
335 fs.unlinkSync(path); |
|
336 assert.equal(fs.existsSync(path), false, "file was removed"); |
|
337 }; |
|
338 |
|
339 |
|
340 exports["test fs.truncate"] = function(assert, end) { |
|
341 let path = truncatePath; |
|
342 if (!fs.existsSync(path)) { |
|
343 let async = false; |
|
344 fs.truncate(path, 0, function(error) { |
|
345 assert.ok(async, "truncate is async"); |
|
346 assert.ok(!error, "no error"); |
|
347 assert.equal(fs.existsSync(path), true, "file was created"); |
|
348 fs.unlinkSync(path); |
|
349 assert.equal(fs.existsSync(path), false, "file was removed"); |
|
350 end(); |
|
351 }) |
|
352 async = true; |
|
353 } |
|
354 }; |
|
355 |
|
356 exports["test fs.unlink"] = function(assert, end) { |
|
357 let path = unlinkPath; |
|
358 let async = false; |
|
359 assert.ok(!fs.existsSync(path), "file doesn't exists yet"); |
|
360 fs.truncateSync(path, 0); |
|
361 assert.ok(fs.existsSync(path), "file was created"); |
|
362 fs.unlink(path, function(error) { |
|
363 assert.ok(async, "fs.unlink is async"); |
|
364 assert.ok(!error, "error is falsy"); |
|
365 assert.ok(!fs.existsSync(path), "file was removed"); |
|
366 end(); |
|
367 }); |
|
368 async = true; |
|
369 }; |
|
370 |
|
371 exports["test fs.unlink error"] = function(assert, end) { |
|
372 let path = unlinkPath; |
|
373 let async = false; |
|
374 assert.ok(!fs.existsSync(path), "file doesn't exists yet"); |
|
375 fs.unlink(path, function(error) { |
|
376 assert.ok(async, "fs.unlink is async"); |
|
377 assert.equal(error.message, "ENOENT, remove " + path); |
|
378 assert.equal(error.code, "ENOENT", "error has a code"); |
|
379 assert.equal(error.path, path, "error has a path"); |
|
380 assert.equal(error.errno, 34, "error has a errno"); |
|
381 end(); |
|
382 }); |
|
383 async = true; |
|
384 }; |
|
385 |
|
386 exports["test fs.rename"] = function(assert, end) { |
|
387 let fromPath = renameFromPath; |
|
388 let toPath = renameToPath; |
|
389 |
|
390 fs.truncateSync(fromPath); |
|
391 assert.ok(fs.existsSync(fromPath), "source file exists"); |
|
392 assert.ok(!fs.existsSync(toPath), "destination doesn't exists"); |
|
393 var async = false; |
|
394 fs.rename(fromPath, toPath, function(error) { |
|
395 assert.ok(async, "fs.rename is async"); |
|
396 assert.ok(!error, "error is falsy"); |
|
397 assert.ok(!fs.existsSync(fromPath), "source path no longer exists"); |
|
398 assert.ok(fs.existsSync(toPath), "destination file exists"); |
|
399 fs.unlinkSync(toPath); |
|
400 assert.ok(!fs.existsSync(toPath), "cleaned up properly"); |
|
401 end(); |
|
402 }); |
|
403 async = true; |
|
404 }; |
|
405 |
|
406 exports["test fs.rename (missing source file)"] = function(assert, end) { |
|
407 let fromPath = renameFromPath; |
|
408 let toPath = renameToPath; |
|
409 |
|
410 assert.ok(!fs.existsSync(fromPath), "source file doesn't exists"); |
|
411 assert.ok(!fs.existsSync(toPath), "destination doesn't exists"); |
|
412 var async = false; |
|
413 fs.rename(fromPath, toPath, function(error) { |
|
414 assert.ok(async, "fs.rename is async"); |
|
415 assert.equal(error.message, "ENOENT, rename " + fromPath); |
|
416 assert.equal(error.code, "ENOENT", "error has a code"); |
|
417 assert.equal(error.path, fromPath, "error has a path"); |
|
418 assert.equal(error.errno, 34, "error has a errno"); |
|
419 end(); |
|
420 }); |
|
421 async = true; |
|
422 }; |
|
423 |
|
424 exports["test fs.rename (existing target file)"] = function(assert, end) { |
|
425 let fromPath = renameFromPath; |
|
426 let toPath = renameToPath; |
|
427 |
|
428 fs.truncateSync(fromPath); |
|
429 fs.truncateSync(toPath); |
|
430 assert.ok(fs.existsSync(fromPath), "source file exists"); |
|
431 assert.ok(fs.existsSync(toPath), "destination file exists"); |
|
432 var async = false; |
|
433 fs.rename(fromPath, toPath, function(error) { |
|
434 assert.ok(async, "fs.rename is async"); |
|
435 assert.ok(!error, "error is falsy"); |
|
436 assert.ok(!fs.existsSync(fromPath), "source path no longer exists"); |
|
437 assert.ok(fs.existsSync(toPath), "destination file exists"); |
|
438 fs.unlinkSync(toPath); |
|
439 assert.ok(!fs.existsSync(toPath), "cleaned up properly"); |
|
440 end(); |
|
441 }); |
|
442 async = true; |
|
443 }; |
|
444 |
|
445 exports["test fs.writeFile"] = function(assert, end) { |
|
446 let path = writePath; |
|
447 let content = ["hello world", |
|
448 "this is some text"].join("\n"); |
|
449 |
|
450 var async = false; |
|
451 fs.writeFile(path, content, function(error) { |
|
452 assert.ok(async, "fs write is async"); |
|
453 assert.ok(!error, "error is falsy"); |
|
454 assert.ok(fs.existsSync(path), "file was created"); |
|
455 assert.equal(fs.readFileSync(path).toString(), |
|
456 content, |
|
457 "contet was written"); |
|
458 fs.unlinkSync(path); |
|
459 assert.ok(!fs.exists(path), "file was removed"); |
|
460 |
|
461 end(); |
|
462 }); |
|
463 async = true; |
|
464 }; |
|
465 |
|
466 exports["test fs.writeFile (with large files)"] = function(assert, end) { |
|
467 let path = writePath; |
|
468 let content = ""; |
|
469 |
|
470 for (var i = 0; i < 100000; i++) { |
|
471 content += "buffer\n"; |
|
472 } |
|
473 |
|
474 var async = false; |
|
475 fs.writeFile(path, content, function(error) { |
|
476 assert.ok(async, "fs write is async"); |
|
477 assert.ok(!error, "error is falsy"); |
|
478 assert.ok(fs.existsSync(path), "file was created"); |
|
479 assert.equal(fs.readFileSync(path).toString(), |
|
480 content, |
|
481 "contet was written"); |
|
482 fs.unlinkSync(path); |
|
483 assert.ok(!fs.exists(path), "file was removed"); |
|
484 |
|
485 end(); |
|
486 }); |
|
487 async = true; |
|
488 }; |
|
489 |
|
490 exports["test fs.writeFile error"] = function (assert, done) { |
|
491 try { |
|
492 fs.writeFile({}, 'content', function (err) { |
|
493 assert.fail('Error thrown from TypeError should not be caught'); |
|
494 }); |
|
495 } catch (e) { |
|
496 assert.ok(e, |
|
497 'writeFile with a non-string error should not be caught'); |
|
498 assert.equal(e.name, 'TypeError', 'error should be TypeError'); |
|
499 } |
|
500 fs.writeFile('not/a/valid/path', 'content', function (err) { |
|
501 assert.ok(err, 'error caught and handled in callback'); |
|
502 done(); |
|
503 }); |
|
504 }; |
|
505 |
|
506 exports["test fs.chmod"] = function (assert, done) { |
|
507 let content = ["hej från sverige"]; |
|
508 |
|
509 fs.writeFile(chmodPath, content, function (err) { |
|
510 testPerm("0755")() |
|
511 .then(testPerm("0777")) |
|
512 .then(testPerm("0666")) |
|
513 .then(testPerm(parseInt("0511", 8))) |
|
514 .then(testPerm(parseInt("0200", 8))) |
|
515 .then(testPerm("0040")) |
|
516 .then(testPerm("0000")) |
|
517 .then(testPermSync(parseInt("0777", 8))) |
|
518 .then(testPermSync(parseInt("0666", 8))) |
|
519 .then(testPermSync("0511")) |
|
520 .then(testPermSync("0200")) |
|
521 .then(testPermSync("0040")) |
|
522 .then(testPermSync("0000")) |
|
523 .then(() => { |
|
524 assert.pass("Successful chmod passes"); |
|
525 }, assert.fail) |
|
526 // Test invalid paths |
|
527 .then(() => chmod("not-a-valid-file", parseInt("0755", 8))) |
|
528 .then(assert.fail, (err) => { |
|
529 checkPermError(err, "not-a-valid-file"); |
|
530 }) |
|
531 .then(() => chmod("not-a-valid-file", parseInt("0755", 8), "sync")) |
|
532 .then(assert.fail, (err) => { |
|
533 checkPermError(err, "not-a-valid-file"); |
|
534 }) |
|
535 // Test invalid files |
|
536 .then(() => chmod("resource://not-a-real-file", parseInt("0755", 8))) |
|
537 .then(assert.fail, (err) => { |
|
538 checkPermError(err, "resource://not-a-real-file"); |
|
539 }) |
|
540 .then(() => chmod("resource://not-a-real-file", parseInt("0755", 8), 'sync')) |
|
541 .then(assert.fail, (err) => { |
|
542 checkPermError(err, "resource://not-a-real-file"); |
|
543 }) |
|
544 .then(done, assert.fail); |
|
545 }); |
|
546 |
|
547 function checkPermError (err, path) { |
|
548 assert.equal(err.message, "ENOENT, chmod " + path); |
|
549 assert.equal(err.code, "ENOENT", "error has a code"); |
|
550 assert.equal(err.path, path, "error has a path"); |
|
551 assert.equal(err.errno, 34, "error has a errno"); |
|
552 } |
|
553 |
|
554 function chmod (path, mode, sync) { |
|
555 let { promise, resolve, reject } = defer(); |
|
556 if (!sync) { |
|
557 fs.chmod(path, mode, (err) => { |
|
558 if (err) reject(err); |
|
559 else resolve(); |
|
560 }); |
|
561 } else { |
|
562 fs.chmodSync(path, mode); |
|
563 resolve(); |
|
564 } |
|
565 return promise; |
|
566 } |
|
567 |
|
568 function testPerm (mode, sync) { |
|
569 return function () { |
|
570 return chmod(chmodPath, mode, sync) |
|
571 .then(() => getPerm(chmodPath)) |
|
572 .then(perm => { |
|
573 let nMode = normalizeMode(mode); |
|
574 if (isWindows) |
|
575 assert.equal(perm, nMode, |
|
576 "mode correctly set to " + mode + " (" + nMode + " on windows)"); |
|
577 else |
|
578 assert.equal(perm, nMode, "mode correctly set to " + nMode); |
|
579 }); |
|
580 }; |
|
581 } |
|
582 |
|
583 function testPermSync (mode) { |
|
584 return testPerm(mode, true); |
|
585 } |
|
586 |
|
587 function getPerm (path) { |
|
588 let { promise, resolve, reject } = defer(); |
|
589 fs.stat(path, function (err, stat) { |
|
590 if (err) reject(err); |
|
591 else resolve(stat.mode); |
|
592 }); |
|
593 return promise; |
|
594 } |
|
595 |
|
596 /* |
|
597 * Converts a unix mode `0755` into a Windows version of unix permissions |
|
598 */ |
|
599 function normalizeMode (mode) { |
|
600 if (typeof mode === "string") |
|
601 mode = parseInt(mode, 8); |
|
602 |
|
603 if (!isWindows) |
|
604 return mode; |
|
605 |
|
606 var ANY_READ = parseInt("0444", 8); |
|
607 var ANY_WRITE = parseInt("0222", 8); |
|
608 var winMode = 0; |
|
609 |
|
610 // On Windows, if WRITE is true, then READ is also true |
|
611 if (mode & ANY_WRITE) |
|
612 winMode |= ANY_WRITE | ANY_READ; |
|
613 // Minimum permissions are READ for Windows |
|
614 else |
|
615 winMode |= ANY_READ; |
|
616 |
|
617 return winMode; |
|
618 } |
|
619 }; |
|
620 |
|
621 require("test").run(exports); |