1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-fs.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,621 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +"use strict"; 1.9 + 1.10 +const { pathFor, platform } = require("sdk/system"); 1.11 +const fs = require("sdk/io/fs"); 1.12 +const url = require("sdk/url"); 1.13 +const path = require("sdk/fs/path"); 1.14 +const { defer } = require("sdk/core/promise"); 1.15 +const { Buffer } = require("sdk/io/buffer"); 1.16 +const { is } = require("sdk/system/xul-app"); 1.17 + 1.18 +// Use profile directory to list / read / write files. 1.19 +const profilePath = pathFor("ProfD"); 1.20 +const fileNameInProfile = "compatibility.ini"; 1.21 +const dirNameInProfile = "extensions"; 1.22 +const filePathInProfile = path.join(profilePath, fileNameInProfile); 1.23 +const dirPathInProfile = path.join(profilePath, dirNameInProfile); 1.24 +const mkdirPath = path.join(profilePath, "sdk-fixture-mkdir"); 1.25 +const writePath = path.join(profilePath, "sdk-fixture-writeFile"); 1.26 +const unlinkPath = path.join(profilePath, "sdk-fixture-unlink"); 1.27 +const truncatePath = path.join(profilePath, "sdk-fixture-truncate"); 1.28 +const renameFromPath = path.join(profilePath, "sdk-fixture-rename-from"); 1.29 +const renameToPath = path.join(profilePath, "sdk-fixture-rename-to"); 1.30 +const chmodPath = path.join(profilePath, "sdk-fixture-chmod"); 1.31 + 1.32 +const profileEntries = [ 1.33 + "compatibility.ini", 1.34 + "extensions", 1.35 + "prefs.js" 1.36 + // There are likely to be a lot more files but we can"t really 1.37 + // on consistent list so we limit to this. 1.38 +]; 1.39 + 1.40 +const isWindows = platform.indexOf('win') === 0; 1.41 + 1.42 +exports["test readdir"] = function(assert, end) { 1.43 + var async = false; 1.44 + fs.readdir(profilePath, function(error, entries) { 1.45 + assert.ok(async, "readdir is async"); 1.46 + assert.ok(!error, "there is no error when reading directory"); 1.47 + assert.ok(profileEntries.length <= entries.length, 1.48 + "got at least number of entries we expect"); 1.49 + assert.ok(profileEntries.every(function(entry) { 1.50 + return entries.indexOf(entry) >= 0; 1.51 + }), "all profiles are present"); 1.52 + end(); 1.53 + }); 1.54 + 1.55 + async = true; 1.56 +}; 1.57 + 1.58 +exports["test readdir error"] = function(assert, end) { 1.59 + var async = false; 1.60 + var path = profilePath + "-does-not-exists"; 1.61 + fs.readdir(path, function(error, entries) { 1.62 + assert.ok(async, "readdir is async"); 1.63 + assert.equal(error.message, "ENOENT, readdir " + path); 1.64 + assert.equal(error.code, "ENOENT", "error has a code"); 1.65 + assert.equal(error.path, path, "error has a path"); 1.66 + assert.equal(error.errno, 34, "error has a errno"); 1.67 + end(); 1.68 + }); 1.69 + 1.70 + async = true; 1.71 +}; 1.72 + 1.73 +exports["test readdirSync"] = function(assert) { 1.74 + var async = false; 1.75 + var entries = fs.readdirSync(profilePath); 1.76 + assert.ok(profileEntries.length <= entries.length, 1.77 + "got at least number of entries we expect"); 1.78 + assert.ok(profileEntries.every(function(entry) { 1.79 + return entries.indexOf(entry) >= 0; 1.80 + }), "all profiles are present"); 1.81 +}; 1.82 + 1.83 +exports["test readdirSync error"] = function(assert) { 1.84 + var async = false; 1.85 + var path = profilePath + "-does-not-exists"; 1.86 + try { 1.87 + fs.readdirSync(path); 1.88 + assert.fail(Error("No error was thrown")); 1.89 + } catch (error) { 1.90 + assert.equal(error.message, "ENOENT, readdir " + path); 1.91 + assert.equal(error.code, "ENOENT", "error has a code"); 1.92 + assert.equal(error.path, path, "error has a path"); 1.93 + assert.equal(error.errno, 34, "error has a errno"); 1.94 + } 1.95 +}; 1.96 + 1.97 +exports["test readFile"] = function(assert, end) { 1.98 + let async = false; 1.99 + fs.readFile(filePathInProfile, function(error, content) { 1.100 + assert.ok(async, "readFile is async"); 1.101 + assert.ok(!error, "error is falsy"); 1.102 + 1.103 + assert.ok(Buffer.isBuffer(content), "readFile returns buffer"); 1.104 + assert.ok(typeof(content.length) === "number", "buffer has length"); 1.105 + assert.ok(content.toString().indexOf("[Compatibility]") >= 0, 1.106 + "content contains expected data"); 1.107 + end(); 1.108 + }); 1.109 + async = true; 1.110 +}; 1.111 + 1.112 +exports["test readFile error"] = function(assert, end) { 1.113 + let async = false; 1.114 + let path = filePathInProfile + "-does-not-exists"; 1.115 + fs.readFile(path, function(error, content) { 1.116 + assert.ok(async, "readFile is async"); 1.117 + assert.equal(error.message, "ENOENT, open " + path); 1.118 + assert.equal(error.code, "ENOENT", "error has a code"); 1.119 + assert.equal(error.path, path, "error has a path"); 1.120 + assert.equal(error.errno, 34, "error has a errno"); 1.121 + 1.122 + end(); 1.123 + }); 1.124 + async = true; 1.125 +}; 1.126 + 1.127 +exports["test readFileSync not implemented"] = function(assert) { 1.128 + let buffer = fs.readFileSync(filePathInProfile); 1.129 + assert.ok(buffer.toString().indexOf("[Compatibility]") >= 0, 1.130 + "read content"); 1.131 +}; 1.132 + 1.133 +exports["test fs.stat file"] = function(assert, end) { 1.134 + let async = false; 1.135 + let path = filePathInProfile; 1.136 + fs.stat(path, function(error, stat) { 1.137 + assert.ok(async, "fs.stat is async"); 1.138 + assert.ok(!error, "error is falsy"); 1.139 + assert.ok(!stat.isDirectory(), "not a dir"); 1.140 + assert.ok(stat.isFile(), "is a file"); 1.141 + assert.ok(!stat.isSymbolicLink(), "isn't a symlink"); 1.142 + assert.ok(typeof(stat.size) === "number", "size is a number"); 1.143 + assert.ok(stat.exists === true, "file exists"); 1.144 + assert.ok(typeof(stat.isBlockDevice()) === "boolean"); 1.145 + assert.ok(typeof(stat.isCharacterDevice()) === "boolean"); 1.146 + assert.ok(typeof(stat.isFIFO()) === "boolean"); 1.147 + assert.ok(typeof(stat.isSocket()) === "boolean"); 1.148 + assert.ok(typeof(stat.hidden) === "boolean"); 1.149 + assert.ok(typeof(stat.writable) === "boolean") 1.150 + assert.ok(stat.readable === true); 1.151 + 1.152 + end(); 1.153 + }); 1.154 + async = true; 1.155 +}; 1.156 + 1.157 +exports["test fs.stat dir"] = function(assert, end) { 1.158 + let async = false; 1.159 + let path = dirPathInProfile; 1.160 + fs.stat(path, function(error, stat) { 1.161 + assert.ok(async, "fs.stat is async"); 1.162 + assert.ok(!error, "error is falsy"); 1.163 + assert.ok(stat.isDirectory(), "is a dir"); 1.164 + assert.ok(!stat.isFile(), "not a file"); 1.165 + assert.ok(!stat.isSymbolicLink(), "isn't a symlink"); 1.166 + assert.ok(typeof(stat.size) === "number", "size is a number"); 1.167 + assert.ok(stat.exists === true, "file exists"); 1.168 + assert.ok(typeof(stat.isBlockDevice()) === "boolean"); 1.169 + assert.ok(typeof(stat.isCharacterDevice()) === "boolean"); 1.170 + assert.ok(typeof(stat.isFIFO()) === "boolean"); 1.171 + assert.ok(typeof(stat.isSocket()) === "boolean"); 1.172 + assert.ok(typeof(stat.hidden) === "boolean"); 1.173 + assert.ok(typeof(stat.writable) === "boolean") 1.174 + assert.ok(typeof(stat.readable) === "boolean"); 1.175 + 1.176 + end(); 1.177 + }); 1.178 + async = true; 1.179 +}; 1.180 + 1.181 +exports["test fs.stat error"] = function(assert, end) { 1.182 + let async = false; 1.183 + let path = filePathInProfile + "-does-not-exists"; 1.184 + fs.stat(path, function(error, stat) { 1.185 + assert.ok(async, "fs.stat is async"); 1.186 + assert.equal(error.message, "ENOENT, stat " + path); 1.187 + assert.equal(error.code, "ENOENT", "error has a code"); 1.188 + assert.equal(error.path, path, "error has a path"); 1.189 + assert.equal(error.errno, 34, "error has a errno"); 1.190 + 1.191 + end(); 1.192 + }); 1.193 + async = true; 1.194 +}; 1.195 + 1.196 +exports["test fs.exists NO"] = function(assert, end) { 1.197 + let async = false 1.198 + let path = filePathInProfile + "-does-not-exists"; 1.199 + fs.exists(path, function(error, value) { 1.200 + assert.ok(async, "fs.exists is async"); 1.201 + assert.ok(!error, "error is falsy"); 1.202 + assert.ok(!value, "file does not exists"); 1.203 + end(); 1.204 + }); 1.205 + async = true; 1.206 +}; 1.207 + 1.208 +exports["test fs.exists YES"] = function(assert, end) { 1.209 + let async = false 1.210 + let path = filePathInProfile 1.211 + fs.exists(path, function(error, value) { 1.212 + assert.ok(async, "fs.exists is async"); 1.213 + assert.ok(!error, "error is falsy"); 1.214 + assert.ok(value, "file exists"); 1.215 + end(); 1.216 + }); 1.217 + async = true; 1.218 +}; 1.219 + 1.220 +exports["test fs.exists NO"] = function(assert, end) { 1.221 + let async = false 1.222 + let path = filePathInProfile + "-does-not-exists"; 1.223 + fs.exists(path, function(error, value) { 1.224 + assert.ok(async, "fs.exists is async"); 1.225 + assert.ok(!error, "error is falsy"); 1.226 + assert.ok(!value, "file does not exists"); 1.227 + end(); 1.228 + }); 1.229 + async = true; 1.230 +}; 1.231 + 1.232 +exports["test fs.existsSync"] = function(assert) { 1.233 + let path = filePathInProfile 1.234 + assert.equal(fs.existsSync(path), true, "exists"); 1.235 + assert.equal(fs.existsSync(path + "-does-not-exists"), false, "exists"); 1.236 +}; 1.237 + 1.238 +exports["test fs.mkdirSync fs.rmdirSync"] = function(assert) { 1.239 + let path = mkdirPath; 1.240 + 1.241 + assert.equal(fs.existsSync(path), false, "does not exists"); 1.242 + fs.mkdirSync(path); 1.243 + assert.equal(fs.existsSync(path), true, "dir was created"); 1.244 + try { 1.245 + fs.mkdirSync(path); 1.246 + assert.fail(Error("mkdir on existing should throw")); 1.247 + } catch (error) { 1.248 + assert.equal(error.message, "EEXIST, mkdir " + path); 1.249 + assert.equal(error.code, "EEXIST", "error has a code"); 1.250 + assert.equal(error.path, path, "error has a path"); 1.251 + assert.equal(error.errno, 47, "error has a errno"); 1.252 + } 1.253 + fs.rmdirSync(path); 1.254 + assert.equal(fs.existsSync(path), false, "dir was removed"); 1.255 +}; 1.256 + 1.257 +exports["test fs.mkdir"] = function(assert, end) { 1.258 + let path = mkdirPath; 1.259 + 1.260 + if (!fs.existsSync(path)) { 1.261 + let async = false; 1.262 + fs.mkdir(path, function(error) { 1.263 + assert.ok(async, "mkdir is async"); 1.264 + assert.ok(!error, "no error"); 1.265 + assert.equal(fs.existsSync(path), true, "dir was created"); 1.266 + fs.rmdirSync(path); 1.267 + assert.equal(fs.existsSync(path), false, "dir was removed"); 1.268 + end(); 1.269 + }); 1.270 + async = true; 1.271 + } 1.272 +}; 1.273 + 1.274 +exports["test fs.mkdir error"] = function(assert, end) { 1.275 + let path = mkdirPath; 1.276 + 1.277 + if (!fs.existsSync(path)) { 1.278 + fs.mkdirSync(path); 1.279 + let async = false; 1.280 + fs.mkdir(path, function(error) { 1.281 + assert.ok(async, "mkdir is async"); 1.282 + assert.equal(error.message, "EEXIST, mkdir " + path); 1.283 + assert.equal(error.code, "EEXIST", "error has a code"); 1.284 + assert.equal(error.path, path, "error has a path"); 1.285 + assert.equal(error.errno, 47, "error has a errno"); 1.286 + fs.rmdirSync(path); 1.287 + assert.equal(fs.existsSync(path), false, "dir was removed"); 1.288 + end(); 1.289 + }); 1.290 + async = true; 1.291 + } 1.292 +}; 1.293 + 1.294 +exports["test fs.rmdir"] = function(assert, end) { 1.295 + let path = mkdirPath; 1.296 + 1.297 + if (!fs.existsSync(path)) { 1.298 + fs.mkdirSync(path); 1.299 + assert.equal(fs.existsSync(path), true, "dir exists"); 1.300 + let async = false; 1.301 + fs.rmdir(path, function(error) { 1.302 + assert.ok(async, "mkdir is async"); 1.303 + assert.ok(!error, "no error"); 1.304 + assert.equal(fs.existsSync(path), false, "dir was removed"); 1.305 + end(); 1.306 + }); 1.307 + async = true; 1.308 + } 1.309 +}; 1.310 + 1.311 + 1.312 +exports["test fs.rmdir error"] = function(assert, end) { 1.313 + let path = mkdirPath; 1.314 + 1.315 + if (!fs.existsSync(path)) { 1.316 + assert.equal(fs.existsSync(path), false, "dir doesn't exists"); 1.317 + let async = false; 1.318 + fs.rmdir(path, function(error) { 1.319 + assert.ok(async, "mkdir is async"); 1.320 + assert.equal(error.message, "ENOENT, remove " + path); 1.321 + assert.equal(error.code, "ENOENT", "error has a code"); 1.322 + assert.equal(error.path, path, "error has a path"); 1.323 + assert.equal(error.errno, 34, "error has a errno"); 1.324 + assert.equal(fs.existsSync(path), false, "dir is removed"); 1.325 + end(); 1.326 + }); 1.327 + async = true; 1.328 + } 1.329 +}; 1.330 + 1.331 +exports["test fs.truncateSync fs.unlinkSync"] = function(assert) { 1.332 + let path = truncatePath; 1.333 + 1.334 + assert.equal(fs.existsSync(path), false, "does not exists"); 1.335 + fs.truncateSync(path); 1.336 + assert.equal(fs.existsSync(path), true, "file was created"); 1.337 + fs.truncateSync(path); 1.338 + fs.unlinkSync(path); 1.339 + assert.equal(fs.existsSync(path), false, "file was removed"); 1.340 +}; 1.341 + 1.342 + 1.343 +exports["test fs.truncate"] = function(assert, end) { 1.344 + let path = truncatePath; 1.345 + if (!fs.existsSync(path)) { 1.346 + let async = false; 1.347 + fs.truncate(path, 0, function(error) { 1.348 + assert.ok(async, "truncate is async"); 1.349 + assert.ok(!error, "no error"); 1.350 + assert.equal(fs.existsSync(path), true, "file was created"); 1.351 + fs.unlinkSync(path); 1.352 + assert.equal(fs.existsSync(path), false, "file was removed"); 1.353 + end(); 1.354 + }) 1.355 + async = true; 1.356 + } 1.357 +}; 1.358 + 1.359 +exports["test fs.unlink"] = function(assert, end) { 1.360 + let path = unlinkPath; 1.361 + let async = false; 1.362 + assert.ok(!fs.existsSync(path), "file doesn't exists yet"); 1.363 + fs.truncateSync(path, 0); 1.364 + assert.ok(fs.existsSync(path), "file was created"); 1.365 + fs.unlink(path, function(error) { 1.366 + assert.ok(async, "fs.unlink is async"); 1.367 + assert.ok(!error, "error is falsy"); 1.368 + assert.ok(!fs.existsSync(path), "file was removed"); 1.369 + end(); 1.370 + }); 1.371 + async = true; 1.372 +}; 1.373 + 1.374 +exports["test fs.unlink error"] = function(assert, end) { 1.375 + let path = unlinkPath; 1.376 + let async = false; 1.377 + assert.ok(!fs.existsSync(path), "file doesn't exists yet"); 1.378 + fs.unlink(path, function(error) { 1.379 + assert.ok(async, "fs.unlink is async"); 1.380 + assert.equal(error.message, "ENOENT, remove " + path); 1.381 + assert.equal(error.code, "ENOENT", "error has a code"); 1.382 + assert.equal(error.path, path, "error has a path"); 1.383 + assert.equal(error.errno, 34, "error has a errno"); 1.384 + end(); 1.385 + }); 1.386 + async = true; 1.387 +}; 1.388 + 1.389 +exports["test fs.rename"] = function(assert, end) { 1.390 + let fromPath = renameFromPath; 1.391 + let toPath = renameToPath; 1.392 + 1.393 + fs.truncateSync(fromPath); 1.394 + assert.ok(fs.existsSync(fromPath), "source file exists"); 1.395 + assert.ok(!fs.existsSync(toPath), "destination doesn't exists"); 1.396 + var async = false; 1.397 + fs.rename(fromPath, toPath, function(error) { 1.398 + assert.ok(async, "fs.rename is async"); 1.399 + assert.ok(!error, "error is falsy"); 1.400 + assert.ok(!fs.existsSync(fromPath), "source path no longer exists"); 1.401 + assert.ok(fs.existsSync(toPath), "destination file exists"); 1.402 + fs.unlinkSync(toPath); 1.403 + assert.ok(!fs.existsSync(toPath), "cleaned up properly"); 1.404 + end(); 1.405 + }); 1.406 + async = true; 1.407 +}; 1.408 + 1.409 +exports["test fs.rename (missing source file)"] = function(assert, end) { 1.410 + let fromPath = renameFromPath; 1.411 + let toPath = renameToPath; 1.412 + 1.413 + assert.ok(!fs.existsSync(fromPath), "source file doesn't exists"); 1.414 + assert.ok(!fs.existsSync(toPath), "destination doesn't exists"); 1.415 + var async = false; 1.416 + fs.rename(fromPath, toPath, function(error) { 1.417 + assert.ok(async, "fs.rename is async"); 1.418 + assert.equal(error.message, "ENOENT, rename " + fromPath); 1.419 + assert.equal(error.code, "ENOENT", "error has a code"); 1.420 + assert.equal(error.path, fromPath, "error has a path"); 1.421 + assert.equal(error.errno, 34, "error has a errno"); 1.422 + end(); 1.423 + }); 1.424 + async = true; 1.425 +}; 1.426 + 1.427 +exports["test fs.rename (existing target file)"] = function(assert, end) { 1.428 + let fromPath = renameFromPath; 1.429 + let toPath = renameToPath; 1.430 + 1.431 + fs.truncateSync(fromPath); 1.432 + fs.truncateSync(toPath); 1.433 + assert.ok(fs.existsSync(fromPath), "source file exists"); 1.434 + assert.ok(fs.existsSync(toPath), "destination file exists"); 1.435 + var async = false; 1.436 + fs.rename(fromPath, toPath, function(error) { 1.437 + assert.ok(async, "fs.rename is async"); 1.438 + assert.ok(!error, "error is falsy"); 1.439 + assert.ok(!fs.existsSync(fromPath), "source path no longer exists"); 1.440 + assert.ok(fs.existsSync(toPath), "destination file exists"); 1.441 + fs.unlinkSync(toPath); 1.442 + assert.ok(!fs.existsSync(toPath), "cleaned up properly"); 1.443 + end(); 1.444 + }); 1.445 + async = true; 1.446 +}; 1.447 + 1.448 +exports["test fs.writeFile"] = function(assert, end) { 1.449 + let path = writePath; 1.450 + let content = ["hello world", 1.451 + "this is some text"].join("\n"); 1.452 + 1.453 + var async = false; 1.454 + fs.writeFile(path, content, function(error) { 1.455 + assert.ok(async, "fs write is async"); 1.456 + assert.ok(!error, "error is falsy"); 1.457 + assert.ok(fs.existsSync(path), "file was created"); 1.458 + assert.equal(fs.readFileSync(path).toString(), 1.459 + content, 1.460 + "contet was written"); 1.461 + fs.unlinkSync(path); 1.462 + assert.ok(!fs.exists(path), "file was removed"); 1.463 + 1.464 + end(); 1.465 + }); 1.466 + async = true; 1.467 +}; 1.468 + 1.469 +exports["test fs.writeFile (with large files)"] = function(assert, end) { 1.470 + let path = writePath; 1.471 + let content = ""; 1.472 + 1.473 + for (var i = 0; i < 100000; i++) { 1.474 + content += "buffer\n"; 1.475 + } 1.476 + 1.477 + var async = false; 1.478 + fs.writeFile(path, content, function(error) { 1.479 + assert.ok(async, "fs write is async"); 1.480 + assert.ok(!error, "error is falsy"); 1.481 + assert.ok(fs.existsSync(path), "file was created"); 1.482 + assert.equal(fs.readFileSync(path).toString(), 1.483 + content, 1.484 + "contet was written"); 1.485 + fs.unlinkSync(path); 1.486 + assert.ok(!fs.exists(path), "file was removed"); 1.487 + 1.488 + end(); 1.489 + }); 1.490 + async = true; 1.491 +}; 1.492 + 1.493 +exports["test fs.writeFile error"] = function (assert, done) { 1.494 + try { 1.495 + fs.writeFile({}, 'content', function (err) { 1.496 + assert.fail('Error thrown from TypeError should not be caught'); 1.497 + }); 1.498 + } catch (e) { 1.499 + assert.ok(e, 1.500 + 'writeFile with a non-string error should not be caught'); 1.501 + assert.equal(e.name, 'TypeError', 'error should be TypeError'); 1.502 + } 1.503 + fs.writeFile('not/a/valid/path', 'content', function (err) { 1.504 + assert.ok(err, 'error caught and handled in callback'); 1.505 + done(); 1.506 + }); 1.507 +}; 1.508 + 1.509 +exports["test fs.chmod"] = function (assert, done) { 1.510 + let content = ["hej från sverige"]; 1.511 + 1.512 + fs.writeFile(chmodPath, content, function (err) { 1.513 + testPerm("0755")() 1.514 + .then(testPerm("0777")) 1.515 + .then(testPerm("0666")) 1.516 + .then(testPerm(parseInt("0511", 8))) 1.517 + .then(testPerm(parseInt("0200", 8))) 1.518 + .then(testPerm("0040")) 1.519 + .then(testPerm("0000")) 1.520 + .then(testPermSync(parseInt("0777", 8))) 1.521 + .then(testPermSync(parseInt("0666", 8))) 1.522 + .then(testPermSync("0511")) 1.523 + .then(testPermSync("0200")) 1.524 + .then(testPermSync("0040")) 1.525 + .then(testPermSync("0000")) 1.526 + .then(() => { 1.527 + assert.pass("Successful chmod passes"); 1.528 + }, assert.fail) 1.529 + // Test invalid paths 1.530 + .then(() => chmod("not-a-valid-file", parseInt("0755", 8))) 1.531 + .then(assert.fail, (err) => { 1.532 + checkPermError(err, "not-a-valid-file"); 1.533 + }) 1.534 + .then(() => chmod("not-a-valid-file", parseInt("0755", 8), "sync")) 1.535 + .then(assert.fail, (err) => { 1.536 + checkPermError(err, "not-a-valid-file"); 1.537 + }) 1.538 + // Test invalid files 1.539 + .then(() => chmod("resource://not-a-real-file", parseInt("0755", 8))) 1.540 + .then(assert.fail, (err) => { 1.541 + checkPermError(err, "resource://not-a-real-file"); 1.542 + }) 1.543 + .then(() => chmod("resource://not-a-real-file", parseInt("0755", 8), 'sync')) 1.544 + .then(assert.fail, (err) => { 1.545 + checkPermError(err, "resource://not-a-real-file"); 1.546 + }) 1.547 + .then(done, assert.fail); 1.548 + }); 1.549 + 1.550 + function checkPermError (err, path) { 1.551 + assert.equal(err.message, "ENOENT, chmod " + path); 1.552 + assert.equal(err.code, "ENOENT", "error has a code"); 1.553 + assert.equal(err.path, path, "error has a path"); 1.554 + assert.equal(err.errno, 34, "error has a errno"); 1.555 + } 1.556 + 1.557 + function chmod (path, mode, sync) { 1.558 + let { promise, resolve, reject } = defer(); 1.559 + if (!sync) { 1.560 + fs.chmod(path, mode, (err) => { 1.561 + if (err) reject(err); 1.562 + else resolve(); 1.563 + }); 1.564 + } else { 1.565 + fs.chmodSync(path, mode); 1.566 + resolve(); 1.567 + } 1.568 + return promise; 1.569 + } 1.570 + 1.571 + function testPerm (mode, sync) { 1.572 + return function () { 1.573 + return chmod(chmodPath, mode, sync) 1.574 + .then(() => getPerm(chmodPath)) 1.575 + .then(perm => { 1.576 + let nMode = normalizeMode(mode); 1.577 + if (isWindows) 1.578 + assert.equal(perm, nMode, 1.579 + "mode correctly set to " + mode + " (" + nMode + " on windows)"); 1.580 + else 1.581 + assert.equal(perm, nMode, "mode correctly set to " + nMode); 1.582 + }); 1.583 + }; 1.584 + } 1.585 + 1.586 + function testPermSync (mode) { 1.587 + return testPerm(mode, true); 1.588 + } 1.589 + 1.590 + function getPerm (path) { 1.591 + let { promise, resolve, reject } = defer(); 1.592 + fs.stat(path, function (err, stat) { 1.593 + if (err) reject(err); 1.594 + else resolve(stat.mode); 1.595 + }); 1.596 + return promise; 1.597 + } 1.598 + 1.599 + /* 1.600 + * Converts a unix mode `0755` into a Windows version of unix permissions 1.601 + */ 1.602 + function normalizeMode (mode) { 1.603 + if (typeof mode === "string") 1.604 + mode = parseInt(mode, 8); 1.605 + 1.606 + if (!isWindows) 1.607 + return mode; 1.608 + 1.609 + var ANY_READ = parseInt("0444", 8); 1.610 + var ANY_WRITE = parseInt("0222", 8); 1.611 + var winMode = 0; 1.612 + 1.613 + // On Windows, if WRITE is true, then READ is also true 1.614 + if (mode & ANY_WRITE) 1.615 + winMode |= ANY_WRITE | ANY_READ; 1.616 + // Minimum permissions are READ for Windows 1.617 + else 1.618 + winMode |= ANY_READ; 1.619 + 1.620 + return winMode; 1.621 + } 1.622 +}; 1.623 + 1.624 +require("test").run(exports);