Browse Source

Do not use Promise in 'fs' module

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

244
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)+ ::
See rename(2).
- on success: no parameters.
- on error: no parameters.
+fs.rename(path1, path2, callback)+ ::
Asynchronous rename(2).
No arguments other than a possible exception are given to the completion callback.
+fs.truncate(fd, len)+ ::
See ftruncate(2).
- on success: no parameters.
- on error: no parameters.
+fs.renameSync(path1, path2)+ ::
Synchronous rename(2).
+fs.chmod(path, mode)+ ::
See chmod(1)
- on success: no parameters.
- on error: no parameters.
+fs.stat(path)+ ::
See stat(2).
- on success: Returns +fs.Stats+ object. It looks like this:
+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.chmod(path, mode, callback)+ ::
Asynchronous chmod(2).
No arguments other than a possible exception are given to the completion callback.
+fs.chmodSync(path, mode)+ ::
Synchronous chmod(2).
+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,91 +693,116 @@ 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)+ ::
See unlink(2)
- on success: no parameters.
- on error: no parameters.
+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.rmdir(path)+ ::
See rmdir(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.mkdir(path, mode)+ ::
See mkdir(2)
- on success: no parameters.
- on error: no parameters.
+fs.rmdirSync(path)+ ::
Synchronous rmdir(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.mkdir(path, mode, callback)+ ::
Asynchronous mkdir(2).
No arguments other than a possible exception are given to the completion callback.
+fs.mkdirSync(path, mode)+ ::
Synchronous mkdir(2).
+fs.close(fd)+ ::
See close(2)
- on success: no parameters.
- 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.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.close(fd, callback)+ ::
Asynchronous close(2).
No arguments other than a possible exception are given to the completion callback.
+fs.write(fd, data, position, encoding)+::
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.
+fs.closeSync(fd)+ ::
Synchronous close(2).
+fs.read(fd, length, position, encoding)+::
Read data from the file specified by +fd+.
+
+length+ is an integer specifying the number of
bytes to read.
+
+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.
+fs.readFile(filename, encoding="utf8")+::
Outputs the entire contents of a file. Example:
+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.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).
+
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, callback)+::
Read data from the file specified by +fd+.
+
+length+ is an integer specifying the number of
bytes to read.
+
+position+ is an integer specifying where to begin
reading from in the file.
+
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", 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+

252
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) {
if (written === _data.length) {
fs.close(fd);
promise.emitSuccess();
} else {
doWrite(_data.slice(written));
}
});
}
doWrite(data);
})
.addErrback(function () {
promise.emitError();
});
exports.chmodSync = function (path, mode) {
return process.fs.chmod(path, mode);
};
return promise;
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) {
exports.close(fd, callback);
} else {
writeAll(fd, data.slice(written), encoding, callback);
}
}
});
}
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) {
content += chunk;
} else {
content = content.concat(chunk);
}
pos += bytes_read;
readChunk();
} else {
promise.emitSuccess(content);
exports.close(fd);
}
}).addErrback(function () {
promise.emitError.apply(promise, arguments);
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 {
process.fs.close(fd, function (err) {
if (callback) callback(err, content);
});
}
readChunk();
}).addErrback(function () {
promise.emitError.apply(promise, arguments);
});
return promise;
}
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 {
readAll(fd, 0, "", encoding, callback);
}
});
};
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

46
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();

12
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) {
puts("error! " + e);
process.exit(1);
fs.readFile(testTxt, function(err, data) {
if (err) {
puts("error! " + e);
process.exit(1);
} else {
puts("finish");
}
});
}
}, 100);

15
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) {
j++; // only makes it to about 17
puts("finish " + j);
})
.addCallback(function () {
puts("won't be called");
// 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);
} else {
throw new Error("this shouldn't be called");
}
});
}

18
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) {
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;
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);
}
});
process.addListener("exit", function () {

28
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 promise = fs.chmod(__file, 0777);
promise.addCallback(function () {
puts(fs.statSync(__file).mode);
assert.equal("777", (fs.statSync(__file).mode & 0777).toString(8));
fs.chmodSync(__file, 0644);
assert.equal("644", (fs.statSync(__file).mode & 0777).toString(8));
success_count++;
});
promise.addErrback(function () {
got_error = true;
var file = path.join(fixturesDir, "a.js");
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(0644, fs.statSync(file).mode & 0777);
success_count++;
}
});
process.addListener("exit", function () {

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

@ -2,53 +2,52 @@ process.mixin(require("./common"));
var got_error = false;
var success_count = 0;
var stats;
var promise = fs.stat(".");
promise.addCallback(function (_stats) {
stats = _stats;
p(stats);
success_count++;
});
promise.addErrback(function () {
got_error = true;
fs.stat(".", function (err, stats) {
if (err) {
got_error = true;
} else {
p(stats);
assert.ok(stats.mtime instanceof Date);
success_count++;
}
});
puts("stating: " + __filename);
fs.stat(__filename).addCallback(function (s) {
p(s);
success_count++;
fs.stat(__filename, function (err, s) {
if (err) {
got_error = true;
} else {
p(s);
success_count++;
puts("isDirectory: " + JSON.stringify( s.isDirectory() ) );
assert.equal(false, s.isDirectory());
puts("isDirectory: " + JSON.stringify( s.isDirectory() ) );
assert.equal(false, s.isDirectory());
puts("isFile: " + JSON.stringify( s.isFile() ) );
assert.equal(true, s.isFile());
puts("isFile: " + JSON.stringify( s.isFile() ) );
assert.equal(true, s.isFile());
puts("isSocket: " + JSON.stringify( s.isSocket() ) );
assert.equal(false, s.isSocket());
puts("isSocket: " + JSON.stringify( s.isSocket() ) );
assert.equal(false, s.isSocket());
puts("isBlockDevice: " + JSON.stringify( s.isBlockDevice() ) );
assert.equal(false, s.isBlockDevice());
puts("isBlockDevice: " + JSON.stringify( s.isBlockDevice() ) );
assert.equal(false, s.isBlockDevice());
puts("isCharacterDevice: " + JSON.stringify( s.isCharacterDevice() ) );
assert.equal(false, s.isCharacterDevice());
puts("isCharacterDevice: " + JSON.stringify( s.isCharacterDevice() ) );
assert.equal(false, s.isCharacterDevice());
puts("isFIFO: " + JSON.stringify( s.isFIFO() ) );
assert.equal(false, s.isFIFO());
puts("isFIFO: " + JSON.stringify( s.isFIFO() ) );
assert.equal(false, s.isFIFO());
puts("isSymbolicLink: " + JSON.stringify( s.isSymbolicLink() ) );
assert.equal(false, s.isSymbolicLink());
}).addErrback(function () {
got_error = true;
});
puts("isSymbolicLink: " + JSON.stringify( s.isSymbolicLink() ) );
assert.equal(false, s.isSymbolicLink());
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);
});

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

@ -4,14 +4,18 @@ 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.unlinkSync(fn);
});
});
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);
});
});

29
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 () {
puts("mkdir okay!");
fs.rmdir(d).addCallback(function () {
puts("rmdir okay!");
}).addErrback(function (e) {
puts("rmdir error: " + e.message);
rmdir_error = true;
});
}).addErrback(function (e) {
puts("mkdir error: " + e.message);
mkdir_error = true;
fs.mkdir(d, 0666, function (err) {
if (err) {
puts("mkdir error: " + err.message);
mkdir_error = true;
} else {
puts("mkdir okay!");
fs.rmdir(d, function (err) {
if (err) {
puts("rmdir error: " + err.message);
rmdir_error = true;
} else {
puts("rmdir okay!");
}
});
}
});
process.addListener("exit", function () {

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

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

44
test/mjsunit/test-readdir.js

@ -2,30 +2,28 @@ process.mixin(require("./common"));
var got_error = false;
var promise = fs.readdir(fixturesDir);
puts("readdir " + fixturesDir);
promise.addCallback(function (files) {
p(files);
assert.deepEqual(['a.js'
, 'b'
, 'cycles'
, 'echo.js'
, 'multipart.js'
, 'nested-index'
, 'print-chars.js'
, 'test_ca.pem'
, 'test_cert.pem'
, 'test_key.pem'
, 'throws_error.js'
, 'x.txt'
], files.sort());
});
promise.addErrback(function () {
puts("error");
got_error = true;
fs.readdir(fixturesDir, function (err, files) {
if (err) {
puts("error");
got_error = true;
} else {
p(files);
assert.deepEqual(['a.js'
, 'b'
, 'cycles'
, 'echo.js'
, 'multipart.js'
, 'nested-index'
, 'print-chars.js'
, 'test_ca.pem'
, 'test_cert.pem'
, 'test_key.pem'
, 'throws_error.js'
, 'x.txt'
], files.sort());
}
});
puts("readdir " + fixturesDir);
process.addListener("exit", function () {
assert.equal(false, got_error);

Loading…
Cancel
Save