Browse Source

Do not use Promise in 'fs' module

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
ef55324f1a
  1. 220
      doc/api.txt
  2. 236
      src/node.js
  3. 44
      test/mjsunit/test-eio-race.js
  4. 8
      test/mjsunit/test-eio-race2.js
  5. 11
      test/mjsunit/test-eio-race4.js
  6. 12
      test/mjsunit/test-file-read-noexist.js
  7. 22
      test/mjsunit/test-fs-chmod.js
  8. 27
      test/mjsunit/test-fs-stat.js
  9. 18
      test/mjsunit/test-fs-write.js
  10. 23
      test/mjsunit/test-mkdir-rmdir.js
  11. 7
      test/mjsunit/test-module-loading.js
  12. 16
      test/mjsunit/test-readdir.js

220
doc/api.txt

@ -236,9 +236,6 @@ Events are represented by a camel-cased string. Here are some examples:
Functions can be then be attached to objects, to be executed when an event
is emitted. These functions are called _listeners_.
Some asynchronous file operations return an +EventEmitter+ called a
_promise_. A promise emits just a single event when the operation is
complete.
=== +events.EventEmitter+
@ -586,60 +583,96 @@ will be sent +"SIGTERM"+. See signal(7) for a list of available signals.
== File System
File I/O is provided by simple wrappers around standard POSIX functions. To
use this module do +require("fs")+. All the methods have a similar form.
They return a promise (+events.Promise+). Example of deleting a file:
use this module do +require("fs")+. All the methods have asynchornous and
synchronous forms.
------------------------------------------------------------------------------
The asynchronous form always take a completion callback as its last
argument. The arguments passed to the completion callback depend on the
method, but the first argument is always reserved for an exception. If the
operation was completed successfully, then the first argument will be +null+
or +undefined+.
Here is an example of the asynchornous version:
-------------------------------------------------------
var fs = require("fs"),
sys = require("sys");
var promise = fs.unlink("/tmp/hello");
promise.addCallback(function () {
fs.unlink("/tmp/hello", function (err) {
if (err) throw err;
sys.puts("successfully deleted /tmp/hello");
});
------------------------------------------------------------------------------
-------------------------------------------------------
Here is the synchronous version:
-------------------------------------------------------
var fs = require("fs"),
sys = require("sys");
fs.unlinkSync("/tmp/hello")
sys.puts("successfully deleted /tmp/hello");
-------------------------------------------------------
This is asynchornous, there is no guaranteed ordering. The following is
prone to error
With the asynchronous methods there is no guaranteed ordering. So the
following is prone to error:
------------------------------------------------------------------------------
fs.rename("/tmp/hello", "/tmp/world");
fs.stat("/tmp/world").addCallback(function (stats) {
------------------------------------------------------
fs.rename("/tmp/hello", "/tmp/world", function (err) {
if (err) throw err;
sys.puts("renamed complete");
});
fs.stat("/tmp/world", function (err, stats) {
if (err) throw err;
sys.puts("stats: " + JSON.stringify(stats));
});
------------------------------------------------------------------------------
------------------------------------------------------
It could be that +fs.stat+ is executed before +fs.rename+.
The correct way to do this is to chain the promises.
The correct way to do this is to chain the callbacks.
------------------------------------------------------------------------------
fs.rename("/tmp/hello", "/tmp/world").addCallback(function () {
fs.stat("/tmp/world").addCallback(function (stats) {
------------------------------------------------------
fs.rename("/tmp/hello", "/tmp/world", function (err) {
if (err) throw err;
fs.stat("/tmp/world", function (err, stats) {
if (err) throw err;
sys.puts("stats: " + JSON.stringify(stats));
});
});
------------------------------------------------------------------------------
------------------------------------------------------
In busy processes, the programmer is _strongly encouraged_ to use the
asynchronous versions of these calls. The synchronous versions will block
the entire process until they complete--halting all connections.
+fs.rename(path1, path2, callback)+ ::
Asynchronous rename(2).
No arguments other than a possible exception are given to the completion callback.
+fs.renameSync(path1, path2)+ ::
Synchronous rename(2).
+fs.truncate(fd, len, callback)+ ::
Asynchronous ftruncate(2).
No arguments other than a possible exception are given to the completion callback.
+fs.truncateSync(fd, len)+ ::
Synchronous ftruncate(2).
+fs.rename(path1, path2)+ ::
See rename(2).
- on success: no parameters.
- on error: no parameters.
+fs.truncate(fd, len)+ ::
See ftruncate(2).
- on success: no parameters.
- on error: no parameters.
+fs.chmod(path, mode, callback)+ ::
Asynchronous chmod(2).
No arguments other than a possible exception are given to the completion callback.
+fs.chmod(path, mode)+ ::
See chmod(1)
- on success: no parameters.
- on error: no parameters.
+fs.chmodSync(path, mode)+ ::
Synchronous chmod(2).
+fs.stat(path)+ ::
See stat(2).
- on success: Returns +fs.Stats+ object. It looks like this:
+fs.stat(path, callback)+ ::
Asynchronous stat(2). The callback gets two arguments +(err, stats)+ where
+stats+ is a +fs.Stats+ object. It looks like this:
+
---------------------------------
{ dev: 2049
@ -660,57 +693,70 @@ See stat(2).
+
See the +fs.Stats+ section below for more information.
- on error: no parameters.
+fs.statSync(path)+ ::
Synchronous stat(2). Returns an instance of +fs.Stats+.
+fs.unlink(path, callback)+ ::
Asynchronous unlink(2).
No arguments other than a possible exception are given to the completion callback.
+fs.unlinkSync(path)+ ::
Synchronous unlink(2).
+fs.unlink(path)+ ::
See unlink(2)
- on success: no parameters.
- on error: no parameters.
+fs.rmdir(path, callback)+ ::
Asynchronous rmdir(2).
No arguments other than a possible exception are given to the completion callback.
+fs.rmdirSync(path)+ ::
Synchronous rmdir(2).
+fs.rmdir(path)+ ::
See rmdir(2)
- on success: no parameters.
- on error: no parameters.
+fs.mkdir(path, mode, callback)+ ::
Asynchronous mkdir(2).
No arguments other than a possible exception are given to the completion callback.
+fs.mkdir(path, mode)+ ::
See mkdir(2)
- on success: no parameters.
- on error: no parameters.
+fs.mkdirSync(path, mode)+ ::
Synchronous mkdir(2).
+fs.readdir(path)+ ::
Reads the contents of a directory.
- on success: One argument, an array containing the names (strings) of the
files in the directory (excluding "." and "..").
- on error: no parameters.
+fs.readdir(path, callback)+ ::
Asynchronous readdir(3). Reads the contents of a directory.
The callback gets two arguments +(err, files)+ where +files+ is an array of
the names of the files in the directory excluding +"."+ and +".."+.
+fs.close(fd)+ ::
See close(2)
- on success: no parameters.
- on error: no parameters.
+fs.close(fd, callback)+ ::
Asynchronous close(2).
No arguments other than a possible exception are given to the completion callback.
+fs.closeSync(fd)+ ::
Synchronous close(2).
+fs.open(path, flags, mode=0666)+::
See open(2). The constants like +O_CREAT+ are defined at +process.O_CREAT+.
Also you can use the strings "r", "r+", "w", "w+", "a", or "a+" as aliases
to the common flag combinations.
- on success: +fd+ is given as the parameter.
- on error: no parameters.
+fs.open(path, flags, mode, callback)+::
Asynchronous file open. See open(2). Flags can be "r", "r+", "w", "w+", "a",
or "a+". The callback gets two arguments +(err, fd)+.
+fs.write(fd, data, position, encoding)+::
+fs.openSync(path, flags, mode)+::
Synchronous open(2).
+fs.write(fd, data, position, encoding, callback)+::
Write data to the file specified by +fd+. +position+ refers to the offset
from the beginning of the file where this data should be written. If
+position+ is +null+, the data will be written at the current position.
See pwrite(2).
- on success: returns an integer +written+ which specifies how many _bytes_ were written.
- on error: no parameters.
+
The callback will be given two arguments +(err, written)+ where +written+
specifies how many _bytes_ were written.
+fs.writeSync(fd, data, position, encoding)+::
Synchronous version of +fs.write()+. Returns the number of bytes written.
+fs.read(fd, length, position, encoding)+::
+fs.read(fd, length, position, encoding, callback)+::
Read data from the file specified by +fd+.
+
+length+ is an integer specifying the number of
@ -719,32 +765,44 @@ See the +fs.Stats+ section below for more information.
+position+ is an integer specifying where to begin
reading from in the file.
+
- on success: returns +data, bytes_read+, what was read from the file.
- on error: no parameters.
The callback is given three arguments, +(err, data, bytesRead)+ where +data+
is a string--what was read--and +bytesRead+ is the number of bytes read.
+fs.readSync(fd, length, position, encoding)+::
Synchronous version of +fs.read+. Returns an array +[data, bytesRead]+.
+fs.readFile(filename, encoding="utf8")+::
Outputs the entire contents of a file. Example:
+fs.readFile(filename, encoding="utf8", callback)+::
Asynchronously reads the entire contents of a file. Example:
+
--------------------------------
fs.readFile("/etc/passwd").addCallback(function (content) {
fs.readFile("/etc/passwd", function (err, data) {
if (err) throw err;
sys.puts(content);
});
--------------------------------
+
- on success: returns +data+, what was read from the file.
- on error: no parameters.
The callback is passed two arguments +(err, data)+, where +data+ is the
contents of the file.
+fs.readFileSync(filename, encoding="utf8")+::
Synchronous version of +fs.readFile+. Returns the contents of the
+filename+.
+fs.writeFile(filename, data, encoding="utf8")+::
Writes data to a file. Example:
+fs.writeFile(filename, data, encoding="utf8", callback)+::
Asynchronously writes data to a file. Example:
+
--------------------------------
fs.writeFile("message.txt", "Hello Node").addCallback(function () {
fs.writeFile("message.txt", "Hello Node", function (err) {
if (err) throw err;
sys.puts("It's saved!");
});
--------------------------------
+
- on success: no parameters.
- on error: no parameters.
+fs.writeFileSync(filename, data, encoding="utf8")+::
The synchronous version of +fs.writeFile+.
=== +fs.Stats+

236
src/node.js

@ -454,17 +454,6 @@ function debug (x) {
var fsModule = createInternalModule("fs", function (exports) {
exports.Stats = process.Stats;
function callback (promise) {
return function (error) {
if (error) {
promise.emitError.apply(promise, arguments);
} else {
promise.emitSuccess.apply(promise,
Array.prototype.slice.call(arguments, 1));
}
};
}
// Used by fs.open and friends
function stringToFlags(flag) {
// Only mess with strings
@ -482,24 +471,22 @@ var fsModule = createInternalModule("fs", function (exports) {
}
}
function noop () {}
// Yes, the follow could be easily DRYed up but I provide the explicit
// list to make the arguments clear.
exports.close = function (fd) {
var promise = new events.Promise();
process.fs.close(fd, callback(promise));
return promise;
exports.close = function (fd, callback) {
process.fs.close(fd, callback || noop);
};
exports.closeSync = function (fd) {
return process.fs.close(fd);
};
exports.open = function (path, flags, mode) {
exports.open = function (path, flags, mode, callback) {
if (mode === undefined) { mode = 0666; }
var promise = new events.Promise();
process.fs.open(path, stringToFlags(flags), mode, callback(promise));
return promise;
process.fs.open(path, stringToFlags(flags), mode, callback || noop);
};
exports.openSync = function (path, flags, mode) {
@ -507,11 +494,9 @@ var fsModule = createInternalModule("fs", function (exports) {
return process.fs.open(path, stringToFlags(flags), mode);
};
exports.read = function (fd, length, position, encoding) {
var promise = new events.Promise();
exports.read = function (fd, length, position, encoding, callback) {
encoding = encoding || "binary";
process.fs.read(fd, length, position, encoding, callback(promise));
return promise;
process.fs.read(fd, length, position, encoding, callback || noop);
};
exports.readSync = function (fd, length, position, encoding) {
@ -519,11 +504,9 @@ var fsModule = createInternalModule("fs", function (exports) {
return process.fs.read(fd, length, position, encoding);
};
exports.write = function (fd, data, position, encoding) {
var promise = new events.Promise();
exports.write = function (fd, data, position, encoding, callback) {
encoding = encoding || "binary";
process.fs.write(fd, data, position, encoding, callback(promise));
return promise;
process.fs.write(fd, data, position, encoding, callback || noop);
};
exports.writeSync = function (fd, data, position, encoding) {
@ -531,160 +514,149 @@ var fsModule = createInternalModule("fs", function (exports) {
return process.fs.write(fd, data, position, encoding);
};
exports.rename = function (oldPath, newPath) {
var promise = new events.Promise();
process.fs.rename(oldPath, newPath, callback(promise));
return promise;
exports.rename = function (oldPath, newPath, callback) {
process.fs.rename(oldPath, newPath, callback || noop);
};
exports.renameSync = function (oldPath, newPath) {
return process.fs.rename(oldPath, newPath);
};
exports.truncate = function (fd, len) {
var promise = new events.Promise();
process.fs.truncate(fd, len, callback(promise));
return promise;
exports.truncate = function (fd, len, callback) {
process.fs.truncate(fd, len, callback || noop);
};
exports.truncateSync = function (fd, len) {
return process.fs.truncate(fd, len);
};
exports.rmdir = function (path) {
var promise = new events.Promise();
process.fs.rmdir(path, callback(promise));
return promise;
exports.rmdir = function (path, callback) {
process.fs.rmdir(path, callback || noop);
};
exports.rmdirSync = function (path) {
return process.fs.rmdir(path);
};
exports.mkdir = function (path, mode) {
var promise = new events.Promise();
process.fs.mkdir(path, mode, callback(promise));
return promise;
exports.mkdir = function (path, mode, callback) {
process.fs.mkdir(path, mode, callback || noop);
};
exports.mkdirSync = function (path, mode) {
return process.fs.mkdir(path, mode);
};
exports.sendfile = function (outFd, inFd, inOffset, length) {
var promise = new events.Promise();
process.fs.sendfile(outFd, inFd, inOffset, length, callback(promise));
return promise;
exports.sendfile = function (outFd, inFd, inOffset, length, callback) {
process.fs.sendfile(outFd, inFd, inOffset, length, callback || noop);
};
exports.sendfileSync = function (outFd, inFd, inOffset, length) {
return process.fs.sendfile(outFd, inFd, inOffset, length);
};
exports.readdir = function (path) {
var promise = new events.Promise();
process.fs.readdir(path, callback(promise));
return promise;
exports.readdir = function (path, callback) {
process.fs.readdir(path, callback || noop);
};
exports.readdirSync = function (path) {
return process.fs.readdir(path);
};
exports.stat = function (path) {
var promise = new events.Promise();
process.fs.stat(path, callback(promise));
return promise;
exports.stat = function (path, callback) {
process.fs.stat(path, callback || noop);
};
exports.statSync = function (path) {
return process.fs.stat(path);
};
exports.unlink = function (path) {
var promise = new events.Promise();
process.fs.unlink(path, callback(promise));
return promise;
exports.unlink = function (path, callback) {
process.fs.unlink(path, callback || noop);
};
exports.unlinkSync = function (path) {
return process.fs.unlink(path);
};
exports.writeFile = function (path, data, encoding) {
var promise = new events.Promise();
encoding = encoding || "utf8"; // default to utf8
exports.chmod = function (path, mode, callback) {
process.fs.chmod(path, mode, callback || noop);
};
fs.open(path, "w")
.addCallback(function (fd) {
function doWrite (_data) {
fs.write(fd, _data, 0, encoding)
.addErrback(function () {
fs.close(fd);
promise.emitError();
})
.addCallback(function (written) {
exports.chmodSync = function (path, mode) {
return process.fs.chmod(path, mode);
};
function writeAll (fd, data, encoding, callback) {
exports.write(fd, data, 0, encoding, function (writeErr, written) {
if (writeErr) {
exports.close(fd, function () {
if (callback) callback(writeErr);
});
} else {
if (written === _data.length) {
fs.close(fd);
promise.emitSuccess();
exports.close(fd, callback);
} else {
doWrite(_data.slice(written));
writeAll(fd, data.slice(written), encoding, callback);
}
});
}
doWrite(data);
})
.addErrback(function () {
promise.emitError();
});
}
return promise;
exports.writeFile = function (path, data, encoding_) {
var encoding = (typeof(encoding) == 'string' ? encoding_ : 'utf8');
var callback_ = arguments[arguments.length - 1];
var callback = (typeof(callback_) == 'function' ? callback_ : null);
exports.open(path, 'w', 0666, function (openErr, fd) {
if (openErr) {
if (callback) callback(openErr);
} else {
writeAll(fd, data, encoding, callback);
}
});
};
exports.writeFileSync = function (path, data, encoding) {
encoding = encoding || "utf8"; // default to utf8
var fd = exports.openSync(path, "w");
return process.fs.write(fd, data, 0, encoding);
var written = 0;
while (written < data.length) {
written += exports.writeSync(fd, data, 0, encoding);
data = data.slice(written);
}
exports.closeSync(fd);
};
exports.cat = function () {
throw new Error("fs.cat is deprecated. Please use fs.readFile instead.");
};
exports.readFile = function (path, encoding) {
var promise = new events.Promise();
encoding = encoding || "utf8"; // default to utf8
exports.open(path, "r").addCallback(function (fd) {
var content = "", pos = 0;
function readChunk () {
exports.read(fd, 16*1024, pos, encoding).addCallback(function (chunk, bytes_read) {
if (chunk) {
if (chunk.constructor === String) {
function readAll (fd, pos, content, encoding, callback) {
exports.read(fd, 4*1024, pos, encoding, function (err, chunk, bytesRead) {
if (err) {
if (callback) callback(err);
} else if (chunk) {
content += chunk;
pos += bytesRead;
readAll(fd, pos, content, encoding, callback);
} else {
content = content.concat(chunk);
process.fs.close(fd, function (err) {
if (callback) callback(err, content);
});
}
});
}
pos += bytes_read;
readChunk();
exports.readFile = function (path, encoding_) {
var encoding = typeof(encoding_) == 'string' ? encoding : 'utf8';
var callback_ = arguments[arguments.length - 1];
var callback = (typeof(callback_) == 'function' ? callback_ : null);
exports.open(path, 'r', 0666, function (err, fd) {
if (err) {
if (callback) callback(err);
} else {
promise.emitSuccess(content);
exports.close(fd);
readAll(fd, 0, "", encoding, callback);
}
}).addErrback(function () {
promise.emitError.apply(promise, arguments);
});
}
readChunk();
}).addErrback(function () {
promise.emitError.apply(promise, arguments);
});
return promise;
};
exports.catSync = function () {
@ -694,30 +666,27 @@ var fsModule = createInternalModule("fs", function (exports) {
exports.readFileSync = function (path, encoding) {
encoding = encoding || "utf8"; // default to utf8
var
fd = exports.openSync(path, "r"),
content = '',
pos = 0,
r;
debug('readFileSync open');
var fd = exports.openSync(path, "r");
var content = '';
var pos = 0;
var r;
while ((r = exports.readSync(fd, 16*1024, pos, encoding)) && r[0]) {
while ((r = exports.readSync(fd, 4*1024, pos, encoding)) && r[0]) {
debug('readFileSync read ' + r[1]);
content += r[0];
pos += r[1]
}
return content;
};
debug('readFileSync close');
exports.chmod = function(path, mode){
var promise = new events.Promise();
process.fs.chmod(path, mode, callback(promise));
return promise;
};
exports.closeSync(fd);
exports.chmodSync = function(path, mode){
return process.fs.chmod(path, mode);
};
debug('readFileSync done');
return content;
};
});
var fs = fsModule.exports;
@ -782,9 +751,9 @@ var pathModule = createInternalModule("path", function (exports) {
};
exports.exists = function (path, callback) {
var p = fs.stat(path);
p.addCallback(function () { callback(true); });
p.addErrback(function () { callback(false); });
fs.stat(path, function (err, stats) {
if (callback) callback(err ? false : true);
});
};
});
@ -1017,13 +986,7 @@ function cat (id, callback) {
}
});
} else {
fs.readFile(id)
.addCallback(function(content) {
if (callback) callback(null, content);
})
.addErrback(function(err) {
if (callback) callback(err);
});
fs.readFile(id, callback);
}
}
@ -1075,6 +1038,7 @@ Module.prototype._loadScriptSync = function (filename) {
Module.prototype._loadScript = function (filename, callback) {
var self = this;
cat(filename, function (err, content) {
debug('cat done');
if (err) {
if (callback) callback(err);
} else {
@ -1130,7 +1094,9 @@ if (process.argv[1].charAt(0) != "/" && !(/^http:\/\//).exec(process.argv[1])) {
// Load the main module--the command line argument.
process.mainModule = new Module(".");
process.mainModule.load(process.argv[1]);
process.mainModule.load(process.argv[1], function (err) {
if (err) throw err;
});
// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If

44
test/mjsunit/test-eio-race.js

@ -1,18 +1,20 @@
process.mixin(require("./common"));
var
count = 100,
fs = require('fs');
var count = 100;
var fs = require('fs');
function tryToKillEventLoop() {
puts('trying to kill event loop ...');
fs.stat(__filename)
.addCallback(function() {
fs.stat(__filename, function (err) {
if (err) {
throw new Exception('first fs.stat failed')
} else {
puts('first fs.stat succeeded ...');
fs.stat(__filename)
.addCallback(function() {
fs.stat(__filename, function (err) {
if (err) {
throw new Exception('second fs.stat failed')
} else {
puts('second fs.stat succeeded ...');
puts('could not kill event loop, retrying...');
@ -23,37 +25,31 @@ function tryToKillEventLoop() {
process.exit(0);
}
}, 1);
})
.addErrback(function() {
throw new Exception('second fs.stat failed')
})
})
.addErrback(function() {
throw new Exception('first fs.stat failed')
}
});
}
});
}
// Generate a lot of thread pool events
var pos = 0;
fs.open('/dev/zero', "r").addCallback(function (rd) {
fs.open('/dev/zero', "r", 0666, function (err, fd) {
if (err) throw err;
function readChunk () {
fs.read(rd, 1024, pos, 'binary').addCallback(function (chunk, bytesRead) {
fs.read(fd, 1024, pos, 'binary', function (err, chunk, bytesRead) {
if (err) throw err;
if (chunk) {
pos += bytesRead;
//puts(pos);
readChunk();
} else {
fs.close(rd);
throw new Exception(BIG_FILE+' should not end before the issue shows up');
fs.closeSync(fd);
throw new Exception('/dev/zero should not end before the issue shows up');
}
}).addErrback(function () {
throw new Exception('could not read from '+BIG_FILE);
});
}
readChunk();
}).addErrback(function () {
throw new Exception('could not open '+BIG_FILE);
});
tryToKillEventLoop();

8
test/mjsunit/test-eio-race2.js

@ -8,11 +8,13 @@ setTimeout(function () {
N = 30;
for (var i=0; i < N; i++) {
puts("start " + i);
fs.readFile(testTxt).addCallback(function(data) {
puts("finish");
}).addErrback(function (e) {
fs.readFile(testTxt, function(err, data) {
if (err) {
puts("error! " + e);
process.exit(1);
} else {
puts("finish");
}
});
}
}, 100);

11
test/mjsunit/test-eio-race4.js

@ -4,13 +4,14 @@ var N = 100;
var j = 0;
for (var i = 0; i < N; i++) {
fs.stat("does-not-exist-" + i) // these files don't exist
.addErrback(function (e) {
// these files don't exist
fs.stat("does-not-exist-" + i, function (err) {
if (err) {
j++; // only makes it to about 17
puts("finish " + j);
})
.addCallback(function () {
puts("won't be called");
} else {
throw new Error("this shouldn't be called");
}
});
}

12
test/mjsunit/test-file-read-noexist.js

@ -2,16 +2,14 @@ process.mixin(require("./common"));
var got_error = false;
var filename = path.join(fixturesDir, "does_not_exist.txt");
var promise = fs.readFile(filename, "raw");
promise.addCallback(function (content) {
fs.readFile(filename, "raw", function (err, content) {
if (err) {
got_error = true;
} else {
debug("cat returned some content: " + content);
debug("this shouldn't happen as the file doesn't exist...");
assert.equal(true, false);
});
promise.addErrback(function () {
got_error = true;
}
});
process.addListener("exit", function () {

22
test/mjsunit/test-fs-chmod.js

@ -3,21 +3,19 @@ process.mixin(require("./common"));
var got_error = false;
var success_count = 0;
var __file = path.join(fixturesDir, "a.js");
var file = path.join(fixturesDir, "a.js");
var promise = fs.chmod(__file, 0777);
promise.addCallback(function () {
puts(fs.statSync(__file).mode);
assert.equal("777", (fs.statSync(__file).mode & 0777).toString(8));
fs.chmod(file, 0777, function (err) {
if (err) {
got_error = true;
} else {
puts(fs.statSync(file).mode);
assert.equal(0777, fs.statSync(file).mode & 0777);
fs.chmodSync(__file, 0644);
assert.equal("644", (fs.statSync(__file).mode & 0777).toString(8));
fs.chmodSync(file, 0644);
assert.equal(0644, fs.statSync(file).mode & 0777);
success_count++;
});
promise.addErrback(function () {
got_error = true;
}
});
process.addListener("exit", function () {

27
test/mjsunit/test-fs-stat.js

@ -2,22 +2,22 @@ process.mixin(require("./common"));
var got_error = false;
var success_count = 0;
var stats;
var promise = fs.stat(".");
promise.addCallback(function (_stats) {
stats = _stats;
fs.stat(".", function (err, stats) {
if (err) {
got_error = true;
} else {
p(stats);
assert.ok(stats.mtime instanceof Date);
success_count++;
});
promise.addErrback(function () {
got_error = true;
}
});
puts("stating: " + __filename);
fs.stat(__filename).addCallback(function (s) {
fs.stat(__filename, function (err, s) {
if (err) {
got_error = true;
} else {
p(s);
success_count++;
@ -41,14 +41,13 @@ fs.stat(__filename).addCallback(function (s) {
puts("isSymbolicLink: " + JSON.stringify( s.isSymbolicLink() ) );
assert.equal(false, s.isSymbolicLink());
}).addErrback(function () {
got_error = true;
});
assert.ok(s.mtime instanceof Date);
}
});
process.addListener("exit", function () {
assert.equal(2, success_count);
assert.equal(false, got_error);
assert.equal(true, stats.mtime instanceof Date);
});

18
test/mjsunit/test-fs-write.js

@ -4,16 +4,20 @@ var fn = path.join(fixturesDir, "write.txt");
var expected = "hello";
var found;
fs.open(fn, 'w', 0644).addCallback(function (file) {
fs.write(file, expected, 0, "utf8").addCallback(function() {
fs.close(file).addCallback(function() {
fs.readFile(fn, process.UTF8).addCallback(function(contents) {
found = contents;
fs.open(fn, 'w', 0644, function (err, fd) {
if (err) throw err;
puts('open done');
fs.write(fd, expected, 0, "utf8", function (err, written) {
puts('write done');
if (err) throw err;
assert.equal(expected.length, written);
fs.closeSync(fd);
found = fs.readFileSync(fn, 'utf8');
puts('expected: ' + expected.toJSON());
puts('found: ' + found.toJSON());
fs.unlinkSync(fn);
});
});
});
});
process.addListener("exit", function () {
assert.equal(expected, found);

23
test/mjsunit/test-mkdir-rmdir.js

@ -7,20 +7,21 @@ var d = path.join(fixtures, "dir");
var mkdir_error = false;
var rmdir_error = false;
fs.mkdir(d, 0x666).addCallback(function () {
fs.mkdir(d, 0666, function (err) {
if (err) {
puts("mkdir error: " + err.message);
mkdir_error = true;
} else {
puts("mkdir okay!");
fs.rmdir(d).addCallback(function () {
puts("rmdir okay!");
}).addErrback(function (e) {
puts("rmdir error: " + e.message);
fs.rmdir(d, function (err) {
if (err) {
puts("rmdir error: " + err.message);
rmdir_error = true;
} else {
puts("rmdir okay!");
}
});
}).addErrback(function (e) {
puts("mkdir error: " + e.message);
mkdir_error = true;
}
});
process.addListener("exit", function () {

7
test/mjsunit/test-module-loading.js

@ -57,12 +57,9 @@ try {
assert.equal(require('path').dirname(__filename), __dirname);
require.async('./fixtures/a')
.addCallback(function(a) {
require.async('./fixtures/a', function (err, a) {
if (err) throw err;
assert.equal("A", a.A());
})
.addErrback(function() {
assert.ok(false, 'async loading broken?');
});
process.addListener("exit", function () {

16
test/mjsunit/test-readdir.js

@ -2,10 +2,11 @@ process.mixin(require("./common"));
var got_error = false;
var promise = fs.readdir(fixturesDir);
puts("readdir " + fixturesDir);
promise.addCallback(function (files) {
fs.readdir(fixturesDir, function (err, files) {
if (err) {
puts("error");
got_error = true;
} else {
p(files);
assert.deepEqual(['a.js'
, 'b'
@ -20,12 +21,9 @@ promise.addCallback(function (files) {
, 'throws_error.js'
, 'x.txt'
], files.sort());
}
});
promise.addErrback(function () {
puts("error");
got_error = true;
});
puts("readdir " + fixturesDir);
process.addListener("exit", function () {
assert.equal(false, got_error);

Loading…
Cancel
Save