Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,7 @@ ReadStream.prototype.open = function() {

self.fd = fd;
self.emit('open', fd);
self.emit('ready', fd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would omit fd here, the other streams don’t have this on the event (and it doesn’t make sense to have it for Http2Stream)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed thefd for the ready event.

// start the flow of data.
self.read();
});
Expand Down Expand Up @@ -2141,6 +2142,7 @@ WriteStream.prototype.open = function() {

this.fd = fd;
this.emit('open', fd);
this.emit('ready', fd);
});
};

Expand Down
1 change: 1 addition & 0 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@ function afterConnect(status, handle, req, readable, writable) {
self._unrefTimer();

self.emit('connect');
self.emit('ready');

// start the first read, or get an immediate EOF.
// this doesn't actually consume any bytes, because len=0.
Expand Down
219 changes: 219 additions & 0 deletions test/parallel/test-fs-ready-event-stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
'use strict';
const common = require('../common');

const assert = require('assert');
const fs = require('fs');
const fixtures = require('../common/fixtures');

const fn = fixtures.path('elipses.txt');
const rangeFile = fixtures.path('x.txt');

{
let paused = false;
let bytesRead = 0;

const file = fs.ReadStream(fn);
const fileSize = fs.statSync(fn).size;

assert.strictEqual(file.bytesRead, 0);

file.on('ready', common.mustCall(function(fd) {
file.length = 0;
assert.strictEqual('number', typeof fd);
assert.strictEqual(file.bytesRead, 0);
assert.ok(file.readable);

// GH-535
file.pause();
file.resume();
file.pause();
file.resume();
}));

file.on('data', function(data) {
assert.ok(data instanceof Buffer);
assert.ok(!paused);
file.length += data.length;

bytesRead += data.length;
assert.strictEqual(file.bytesRead, bytesRead);

paused = true;
file.pause();

setTimeout(function() {
paused = false;
file.resume();
}, 10);
});


file.on('end', common.mustCall(function(chunk) {
assert.strictEqual(bytesRead, fileSize);
assert.strictEqual(file.bytesRead, fileSize);
}));


file.on('close', common.mustCall(function() {
assert.strictEqual(bytesRead, fileSize);
assert.strictEqual(file.bytesRead, fileSize);
}));

process.on('exit', function() {
assert.strictEqual(file.length, 30000);
});
}

{
const file = fs.createReadStream(fn, { encoding: 'utf8' });
file.length = 0;
file.on('data', function(data) {
assert.strictEqual('string', typeof data);
file.length += data.length;

for (let i = 0; i < data.length; i++) {
// http://www.fileformat.info/info/unicode/char/2026/index.htm
assert.strictEqual('\u2026', data[i]);
}
});

file.on('close', common.mustCall());

process.on('exit', function() {
assert.strictEqual(file.length, 10000);
});
}

{
const file =
fs.createReadStream(rangeFile, { bufferSize: 1, start: 1, end: 2 });
let contentRead = '';
file.on('data', function(data) {
contentRead += data.toString('utf-8');
});
file.on('end', common.mustCall(function(data) {
assert.strictEqual(contentRead, 'yz');
}));
}

{
const file = fs.createReadStream(rangeFile, { bufferSize: 1, start: 1 });
file.data = '';
file.on('data', function(data) {
file.data += data.toString('utf-8');
});
file.on('end', common.mustCall(function() {
assert.strictEqual(file.data, 'yz\n');
}));
}

{
// Ref: https://github.com/nodejs/node-v0.x-archive/issues/2320
const file = fs.createReadStream(rangeFile, { bufferSize: 1.23, start: 1 });
file.data = '';
file.on('data', function(data) {
file.data += data.toString('utf-8');
});
file.on('end', common.mustCall(function() {
assert.strictEqual(file.data, 'yz\n');
}));
}

common.expectsError(
() => {
fs.createReadStream(rangeFile, { start: 10, end: 2 });
},
{
code: 'ERR_OUT_OF_RANGE',
message: 'The value of "start" is out of range. It must be <= "end". ' +
'Received {start: 10, end: 2}',
type: RangeError
});

{
const stream = fs.createReadStream(rangeFile, { start: 0, end: 0 });
stream.data = '';

stream.on('data', function(chunk) {
stream.data += chunk;
});

stream.on('end', common.mustCall(function() {
assert.strictEqual('x', stream.data);
}));
}

{
// Verify that end works when start is not specified.
const stream = new fs.createReadStream(rangeFile, { end: 1 });
stream.data = '';

stream.on('data', function(chunk) {
stream.data += chunk;
});

stream.on('end', common.mustCall(function() {
assert.strictEqual('xy', stream.data);
}));
}

{
// pause and then resume immediately.
const pauseRes = fs.createReadStream(rangeFile);
pauseRes.pause();
pauseRes.resume();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a lot of these blocks are taken from another test? It might be good to reduce the file so that only the one with the ready event remains

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed all the extra blocks and made it a minimal testcase to only check for ready event.


{
let file = fs.createReadStream(rangeFile, { autoClose: false });
let data = '';
file.on('data', function(chunk) { data += chunk; });
file.on('end', common.mustCall(function() {
assert.strictEqual(data, 'xyz\n');
process.nextTick(function() {
assert(!file.closed);
assert(!file.destroyed);
fileNext();
});
}));

function fileNext() {
// This will tell us if the fd is usable again or not.
file = fs.createReadStream(null, { fd: file.fd, start: 0 });
file.data = '';
file.on('data', function(data) {
file.data += data;
});
file.on('end', common.mustCall(function(err) {
assert.strictEqual(file.data, 'xyz\n');
}));
process.on('exit', function() {
assert(file.closed);
assert(file.destroyed);
});
}
}

{
// Just to make sure autoClose won't close the stream because of error.
const file = fs.createReadStream(null, { fd: 13337, autoClose: false });
file.on('data', common.mustNotCall());
file.on('error', common.mustCall());
process.on('exit', function() {
assert(!file.closed);
assert(!file.destroyed);
assert(file.fd);
});
}

{
// Make sure stream is destroyed when file does not exist.
const file = fs.createReadStream('/path/to/file/that/does/not/exist');
file.on('data', common.mustNotCall());
file.on('error', common.mustCall());

process.on('exit', function() {
assert(!file.closed);
assert(file.destroyed);
});
}
20 changes: 20 additions & 0 deletions test/parallel/test-net-socket-ready-without-cb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';
const common = require('../common');

// This test ensures that socket.connect can be called without callback
// which is optional.

const net = require('net');

const server = net.createServer(common.mustCall(function(conn) {
conn.end();
server.close();
})).listen(0, common.mustCall(function() {
const client = new net.Socket();

client.on('ready', common.mustCall(function() {
client.end();
}));

client.connect(server.address());
}));