michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const { pathFor, platform } = require("sdk/system"); michael@0: const fs = require("sdk/io/fs"); michael@0: const url = require("sdk/url"); michael@0: const path = require("sdk/fs/path"); michael@0: const { defer } = require("sdk/core/promise"); michael@0: const { Buffer } = require("sdk/io/buffer"); michael@0: const { is } = require("sdk/system/xul-app"); michael@0: michael@0: // Use profile directory to list / read / write files. michael@0: const profilePath = pathFor("ProfD"); michael@0: const fileNameInProfile = "compatibility.ini"; michael@0: const dirNameInProfile = "extensions"; michael@0: const filePathInProfile = path.join(profilePath, fileNameInProfile); michael@0: const dirPathInProfile = path.join(profilePath, dirNameInProfile); michael@0: const mkdirPath = path.join(profilePath, "sdk-fixture-mkdir"); michael@0: const writePath = path.join(profilePath, "sdk-fixture-writeFile"); michael@0: const unlinkPath = path.join(profilePath, "sdk-fixture-unlink"); michael@0: const truncatePath = path.join(profilePath, "sdk-fixture-truncate"); michael@0: const renameFromPath = path.join(profilePath, "sdk-fixture-rename-from"); michael@0: const renameToPath = path.join(profilePath, "sdk-fixture-rename-to"); michael@0: const chmodPath = path.join(profilePath, "sdk-fixture-chmod"); michael@0: michael@0: const profileEntries = [ michael@0: "compatibility.ini", michael@0: "extensions", michael@0: "prefs.js" michael@0: // There are likely to be a lot more files but we can"t really michael@0: // on consistent list so we limit to this. michael@0: ]; michael@0: michael@0: const isWindows = platform.indexOf('win') === 0; michael@0: michael@0: exports["test readdir"] = function(assert, end) { michael@0: var async = false; michael@0: fs.readdir(profilePath, function(error, entries) { michael@0: assert.ok(async, "readdir is async"); michael@0: assert.ok(!error, "there is no error when reading directory"); michael@0: assert.ok(profileEntries.length <= entries.length, michael@0: "got at least number of entries we expect"); michael@0: assert.ok(profileEntries.every(function(entry) { michael@0: return entries.indexOf(entry) >= 0; michael@0: }), "all profiles are present"); michael@0: end(); michael@0: }); michael@0: michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test readdir error"] = function(assert, end) { michael@0: var async = false; michael@0: var path = profilePath + "-does-not-exists"; michael@0: fs.readdir(path, function(error, entries) { michael@0: assert.ok(async, "readdir is async"); michael@0: assert.equal(error.message, "ENOENT, readdir " + path); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: end(); michael@0: }); michael@0: michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test readdirSync"] = function(assert) { michael@0: var async = false; michael@0: var entries = fs.readdirSync(profilePath); michael@0: assert.ok(profileEntries.length <= entries.length, michael@0: "got at least number of entries we expect"); michael@0: assert.ok(profileEntries.every(function(entry) { michael@0: return entries.indexOf(entry) >= 0; michael@0: }), "all profiles are present"); michael@0: }; michael@0: michael@0: exports["test readdirSync error"] = function(assert) { michael@0: var async = false; michael@0: var path = profilePath + "-does-not-exists"; michael@0: try { michael@0: fs.readdirSync(path); michael@0: assert.fail(Error("No error was thrown")); michael@0: } catch (error) { michael@0: assert.equal(error.message, "ENOENT, readdir " + path); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: } michael@0: }; michael@0: michael@0: exports["test readFile"] = function(assert, end) { michael@0: let async = false; michael@0: fs.readFile(filePathInProfile, function(error, content) { michael@0: assert.ok(async, "readFile is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: michael@0: assert.ok(Buffer.isBuffer(content), "readFile returns buffer"); michael@0: assert.ok(typeof(content.length) === "number", "buffer has length"); michael@0: assert.ok(content.toString().indexOf("[Compatibility]") >= 0, michael@0: "content contains expected data"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test readFile error"] = function(assert, end) { michael@0: let async = false; michael@0: let path = filePathInProfile + "-does-not-exists"; michael@0: fs.readFile(path, function(error, content) { michael@0: assert.ok(async, "readFile is async"); michael@0: assert.equal(error.message, "ENOENT, open " + path); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test readFileSync not implemented"] = function(assert) { michael@0: let buffer = fs.readFileSync(filePathInProfile); michael@0: assert.ok(buffer.toString().indexOf("[Compatibility]") >= 0, michael@0: "read content"); michael@0: }; michael@0: michael@0: exports["test fs.stat file"] = function(assert, end) { michael@0: let async = false; michael@0: let path = filePathInProfile; michael@0: fs.stat(path, function(error, stat) { michael@0: assert.ok(async, "fs.stat is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(!stat.isDirectory(), "not a dir"); michael@0: assert.ok(stat.isFile(), "is a file"); michael@0: assert.ok(!stat.isSymbolicLink(), "isn't a symlink"); michael@0: assert.ok(typeof(stat.size) === "number", "size is a number"); michael@0: assert.ok(stat.exists === true, "file exists"); michael@0: assert.ok(typeof(stat.isBlockDevice()) === "boolean"); michael@0: assert.ok(typeof(stat.isCharacterDevice()) === "boolean"); michael@0: assert.ok(typeof(stat.isFIFO()) === "boolean"); michael@0: assert.ok(typeof(stat.isSocket()) === "boolean"); michael@0: assert.ok(typeof(stat.hidden) === "boolean"); michael@0: assert.ok(typeof(stat.writable) === "boolean") michael@0: assert.ok(stat.readable === true); michael@0: michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.stat dir"] = function(assert, end) { michael@0: let async = false; michael@0: let path = dirPathInProfile; michael@0: fs.stat(path, function(error, stat) { michael@0: assert.ok(async, "fs.stat is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(stat.isDirectory(), "is a dir"); michael@0: assert.ok(!stat.isFile(), "not a file"); michael@0: assert.ok(!stat.isSymbolicLink(), "isn't a symlink"); michael@0: assert.ok(typeof(stat.size) === "number", "size is a number"); michael@0: assert.ok(stat.exists === true, "file exists"); michael@0: assert.ok(typeof(stat.isBlockDevice()) === "boolean"); michael@0: assert.ok(typeof(stat.isCharacterDevice()) === "boolean"); michael@0: assert.ok(typeof(stat.isFIFO()) === "boolean"); michael@0: assert.ok(typeof(stat.isSocket()) === "boolean"); michael@0: assert.ok(typeof(stat.hidden) === "boolean"); michael@0: assert.ok(typeof(stat.writable) === "boolean") michael@0: assert.ok(typeof(stat.readable) === "boolean"); michael@0: michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.stat error"] = function(assert, end) { michael@0: let async = false; michael@0: let path = filePathInProfile + "-does-not-exists"; michael@0: fs.stat(path, function(error, stat) { michael@0: assert.ok(async, "fs.stat is async"); michael@0: assert.equal(error.message, "ENOENT, stat " + path); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.exists NO"] = function(assert, end) { michael@0: let async = false michael@0: let path = filePathInProfile + "-does-not-exists"; michael@0: fs.exists(path, function(error, value) { michael@0: assert.ok(async, "fs.exists is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(!value, "file does not exists"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.exists YES"] = function(assert, end) { michael@0: let async = false michael@0: let path = filePathInProfile michael@0: fs.exists(path, function(error, value) { michael@0: assert.ok(async, "fs.exists is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(value, "file exists"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.exists NO"] = function(assert, end) { michael@0: let async = false michael@0: let path = filePathInProfile + "-does-not-exists"; michael@0: fs.exists(path, function(error, value) { michael@0: assert.ok(async, "fs.exists is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(!value, "file does not exists"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.existsSync"] = function(assert) { michael@0: let path = filePathInProfile michael@0: assert.equal(fs.existsSync(path), true, "exists"); michael@0: assert.equal(fs.existsSync(path + "-does-not-exists"), false, "exists"); michael@0: }; michael@0: michael@0: exports["test fs.mkdirSync fs.rmdirSync"] = function(assert) { michael@0: let path = mkdirPath; michael@0: michael@0: assert.equal(fs.existsSync(path), false, "does not exists"); michael@0: fs.mkdirSync(path); michael@0: assert.equal(fs.existsSync(path), true, "dir was created"); michael@0: try { michael@0: fs.mkdirSync(path); michael@0: assert.fail(Error("mkdir on existing should throw")); michael@0: } catch (error) { michael@0: assert.equal(error.message, "EEXIST, mkdir " + path); michael@0: assert.equal(error.code, "EEXIST", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 47, "error has a errno"); michael@0: } michael@0: fs.rmdirSync(path); michael@0: assert.equal(fs.existsSync(path), false, "dir was removed"); michael@0: }; michael@0: michael@0: exports["test fs.mkdir"] = function(assert, end) { michael@0: let path = mkdirPath; michael@0: michael@0: if (!fs.existsSync(path)) { michael@0: let async = false; michael@0: fs.mkdir(path, function(error) { michael@0: assert.ok(async, "mkdir is async"); michael@0: assert.ok(!error, "no error"); michael@0: assert.equal(fs.existsSync(path), true, "dir was created"); michael@0: fs.rmdirSync(path); michael@0: assert.equal(fs.existsSync(path), false, "dir was removed"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: } michael@0: }; michael@0: michael@0: exports["test fs.mkdir error"] = function(assert, end) { michael@0: let path = mkdirPath; michael@0: michael@0: if (!fs.existsSync(path)) { michael@0: fs.mkdirSync(path); michael@0: let async = false; michael@0: fs.mkdir(path, function(error) { michael@0: assert.ok(async, "mkdir is async"); michael@0: assert.equal(error.message, "EEXIST, mkdir " + path); michael@0: assert.equal(error.code, "EEXIST", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 47, "error has a errno"); michael@0: fs.rmdirSync(path); michael@0: assert.equal(fs.existsSync(path), false, "dir was removed"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: } michael@0: }; michael@0: michael@0: exports["test fs.rmdir"] = function(assert, end) { michael@0: let path = mkdirPath; michael@0: michael@0: if (!fs.existsSync(path)) { michael@0: fs.mkdirSync(path); michael@0: assert.equal(fs.existsSync(path), true, "dir exists"); michael@0: let async = false; michael@0: fs.rmdir(path, function(error) { michael@0: assert.ok(async, "mkdir is async"); michael@0: assert.ok(!error, "no error"); michael@0: assert.equal(fs.existsSync(path), false, "dir was removed"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: } michael@0: }; michael@0: michael@0: michael@0: exports["test fs.rmdir error"] = function(assert, end) { michael@0: let path = mkdirPath; michael@0: michael@0: if (!fs.existsSync(path)) { michael@0: assert.equal(fs.existsSync(path), false, "dir doesn't exists"); michael@0: let async = false; michael@0: fs.rmdir(path, function(error) { michael@0: assert.ok(async, "mkdir is async"); michael@0: assert.equal(error.message, "ENOENT, remove " + path); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: assert.equal(fs.existsSync(path), false, "dir is removed"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: } michael@0: }; michael@0: michael@0: exports["test fs.truncateSync fs.unlinkSync"] = function(assert) { michael@0: let path = truncatePath; michael@0: michael@0: assert.equal(fs.existsSync(path), false, "does not exists"); michael@0: fs.truncateSync(path); michael@0: assert.equal(fs.existsSync(path), true, "file was created"); michael@0: fs.truncateSync(path); michael@0: fs.unlinkSync(path); michael@0: assert.equal(fs.existsSync(path), false, "file was removed"); michael@0: }; michael@0: michael@0: michael@0: exports["test fs.truncate"] = function(assert, end) { michael@0: let path = truncatePath; michael@0: if (!fs.existsSync(path)) { michael@0: let async = false; michael@0: fs.truncate(path, 0, function(error) { michael@0: assert.ok(async, "truncate is async"); michael@0: assert.ok(!error, "no error"); michael@0: assert.equal(fs.existsSync(path), true, "file was created"); michael@0: fs.unlinkSync(path); michael@0: assert.equal(fs.existsSync(path), false, "file was removed"); michael@0: end(); michael@0: }) michael@0: async = true; michael@0: } michael@0: }; michael@0: michael@0: exports["test fs.unlink"] = function(assert, end) { michael@0: let path = unlinkPath; michael@0: let async = false; michael@0: assert.ok(!fs.existsSync(path), "file doesn't exists yet"); michael@0: fs.truncateSync(path, 0); michael@0: assert.ok(fs.existsSync(path), "file was created"); michael@0: fs.unlink(path, function(error) { michael@0: assert.ok(async, "fs.unlink is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(!fs.existsSync(path), "file was removed"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.unlink error"] = function(assert, end) { michael@0: let path = unlinkPath; michael@0: let async = false; michael@0: assert.ok(!fs.existsSync(path), "file doesn't exists yet"); michael@0: fs.unlink(path, function(error) { michael@0: assert.ok(async, "fs.unlink is async"); michael@0: assert.equal(error.message, "ENOENT, remove " + path); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, path, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.rename"] = function(assert, end) { michael@0: let fromPath = renameFromPath; michael@0: let toPath = renameToPath; michael@0: michael@0: fs.truncateSync(fromPath); michael@0: assert.ok(fs.existsSync(fromPath), "source file exists"); michael@0: assert.ok(!fs.existsSync(toPath), "destination doesn't exists"); michael@0: var async = false; michael@0: fs.rename(fromPath, toPath, function(error) { michael@0: assert.ok(async, "fs.rename is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(!fs.existsSync(fromPath), "source path no longer exists"); michael@0: assert.ok(fs.existsSync(toPath), "destination file exists"); michael@0: fs.unlinkSync(toPath); michael@0: assert.ok(!fs.existsSync(toPath), "cleaned up properly"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.rename (missing source file)"] = function(assert, end) { michael@0: let fromPath = renameFromPath; michael@0: let toPath = renameToPath; michael@0: michael@0: assert.ok(!fs.existsSync(fromPath), "source file doesn't exists"); michael@0: assert.ok(!fs.existsSync(toPath), "destination doesn't exists"); michael@0: var async = false; michael@0: fs.rename(fromPath, toPath, function(error) { michael@0: assert.ok(async, "fs.rename is async"); michael@0: assert.equal(error.message, "ENOENT, rename " + fromPath); michael@0: assert.equal(error.code, "ENOENT", "error has a code"); michael@0: assert.equal(error.path, fromPath, "error has a path"); michael@0: assert.equal(error.errno, 34, "error has a errno"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.rename (existing target file)"] = function(assert, end) { michael@0: let fromPath = renameFromPath; michael@0: let toPath = renameToPath; michael@0: michael@0: fs.truncateSync(fromPath); michael@0: fs.truncateSync(toPath); michael@0: assert.ok(fs.existsSync(fromPath), "source file exists"); michael@0: assert.ok(fs.existsSync(toPath), "destination file exists"); michael@0: var async = false; michael@0: fs.rename(fromPath, toPath, function(error) { michael@0: assert.ok(async, "fs.rename is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(!fs.existsSync(fromPath), "source path no longer exists"); michael@0: assert.ok(fs.existsSync(toPath), "destination file exists"); michael@0: fs.unlinkSync(toPath); michael@0: assert.ok(!fs.existsSync(toPath), "cleaned up properly"); michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.writeFile"] = function(assert, end) { michael@0: let path = writePath; michael@0: let content = ["hello world", michael@0: "this is some text"].join("\n"); michael@0: michael@0: var async = false; michael@0: fs.writeFile(path, content, function(error) { michael@0: assert.ok(async, "fs write is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(fs.existsSync(path), "file was created"); michael@0: assert.equal(fs.readFileSync(path).toString(), michael@0: content, michael@0: "contet was written"); michael@0: fs.unlinkSync(path); michael@0: assert.ok(!fs.exists(path), "file was removed"); michael@0: michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.writeFile (with large files)"] = function(assert, end) { michael@0: let path = writePath; michael@0: let content = ""; michael@0: michael@0: for (var i = 0; i < 100000; i++) { michael@0: content += "buffer\n"; michael@0: } michael@0: michael@0: var async = false; michael@0: fs.writeFile(path, content, function(error) { michael@0: assert.ok(async, "fs write is async"); michael@0: assert.ok(!error, "error is falsy"); michael@0: assert.ok(fs.existsSync(path), "file was created"); michael@0: assert.equal(fs.readFileSync(path).toString(), michael@0: content, michael@0: "contet was written"); michael@0: fs.unlinkSync(path); michael@0: assert.ok(!fs.exists(path), "file was removed"); michael@0: michael@0: end(); michael@0: }); michael@0: async = true; michael@0: }; michael@0: michael@0: exports["test fs.writeFile error"] = function (assert, done) { michael@0: try { michael@0: fs.writeFile({}, 'content', function (err) { michael@0: assert.fail('Error thrown from TypeError should not be caught'); michael@0: }); michael@0: } catch (e) { michael@0: assert.ok(e, michael@0: 'writeFile with a non-string error should not be caught'); michael@0: assert.equal(e.name, 'TypeError', 'error should be TypeError'); michael@0: } michael@0: fs.writeFile('not/a/valid/path', 'content', function (err) { michael@0: assert.ok(err, 'error caught and handled in callback'); michael@0: done(); michael@0: }); michael@0: }; michael@0: michael@0: exports["test fs.chmod"] = function (assert, done) { michael@0: let content = ["hej från sverige"]; michael@0: michael@0: fs.writeFile(chmodPath, content, function (err) { michael@0: testPerm("0755")() michael@0: .then(testPerm("0777")) michael@0: .then(testPerm("0666")) michael@0: .then(testPerm(parseInt("0511", 8))) michael@0: .then(testPerm(parseInt("0200", 8))) michael@0: .then(testPerm("0040")) michael@0: .then(testPerm("0000")) michael@0: .then(testPermSync(parseInt("0777", 8))) michael@0: .then(testPermSync(parseInt("0666", 8))) michael@0: .then(testPermSync("0511")) michael@0: .then(testPermSync("0200")) michael@0: .then(testPermSync("0040")) michael@0: .then(testPermSync("0000")) michael@0: .then(() => { michael@0: assert.pass("Successful chmod passes"); michael@0: }, assert.fail) michael@0: // Test invalid paths michael@0: .then(() => chmod("not-a-valid-file", parseInt("0755", 8))) michael@0: .then(assert.fail, (err) => { michael@0: checkPermError(err, "not-a-valid-file"); michael@0: }) michael@0: .then(() => chmod("not-a-valid-file", parseInt("0755", 8), "sync")) michael@0: .then(assert.fail, (err) => { michael@0: checkPermError(err, "not-a-valid-file"); michael@0: }) michael@0: // Test invalid files michael@0: .then(() => chmod("resource://not-a-real-file", parseInt("0755", 8))) michael@0: .then(assert.fail, (err) => { michael@0: checkPermError(err, "resource://not-a-real-file"); michael@0: }) michael@0: .then(() => chmod("resource://not-a-real-file", parseInt("0755", 8), 'sync')) michael@0: .then(assert.fail, (err) => { michael@0: checkPermError(err, "resource://not-a-real-file"); michael@0: }) michael@0: .then(done, assert.fail); michael@0: }); michael@0: michael@0: function checkPermError (err, path) { michael@0: assert.equal(err.message, "ENOENT, chmod " + path); michael@0: assert.equal(err.code, "ENOENT", "error has a code"); michael@0: assert.equal(err.path, path, "error has a path"); michael@0: assert.equal(err.errno, 34, "error has a errno"); michael@0: } michael@0: michael@0: function chmod (path, mode, sync) { michael@0: let { promise, resolve, reject } = defer(); michael@0: if (!sync) { michael@0: fs.chmod(path, mode, (err) => { michael@0: if (err) reject(err); michael@0: else resolve(); michael@0: }); michael@0: } else { michael@0: fs.chmodSync(path, mode); michael@0: resolve(); michael@0: } michael@0: return promise; michael@0: } michael@0: michael@0: function testPerm (mode, sync) { michael@0: return function () { michael@0: return chmod(chmodPath, mode, sync) michael@0: .then(() => getPerm(chmodPath)) michael@0: .then(perm => { michael@0: let nMode = normalizeMode(mode); michael@0: if (isWindows) michael@0: assert.equal(perm, nMode, michael@0: "mode correctly set to " + mode + " (" + nMode + " on windows)"); michael@0: else michael@0: assert.equal(perm, nMode, "mode correctly set to " + nMode); michael@0: }); michael@0: }; michael@0: } michael@0: michael@0: function testPermSync (mode) { michael@0: return testPerm(mode, true); michael@0: } michael@0: michael@0: function getPerm (path) { michael@0: let { promise, resolve, reject } = defer(); michael@0: fs.stat(path, function (err, stat) { michael@0: if (err) reject(err); michael@0: else resolve(stat.mode); michael@0: }); michael@0: return promise; michael@0: } michael@0: michael@0: /* michael@0: * Converts a unix mode `0755` into a Windows version of unix permissions michael@0: */ michael@0: function normalizeMode (mode) { michael@0: if (typeof mode === "string") michael@0: mode = parseInt(mode, 8); michael@0: michael@0: if (!isWindows) michael@0: return mode; michael@0: michael@0: var ANY_READ = parseInt("0444", 8); michael@0: var ANY_WRITE = parseInt("0222", 8); michael@0: var winMode = 0; michael@0: michael@0: // On Windows, if WRITE is true, then READ is also true michael@0: if (mode & ANY_WRITE) michael@0: winMode |= ANY_WRITE | ANY_READ; michael@0: // Minimum permissions are READ for Windows michael@0: else michael@0: winMode |= ANY_READ; michael@0: michael@0: return winMode; michael@0: } michael@0: }; michael@0: michael@0: require("test").run(exports);