metro-memory-fs: clean up createWriteStream()

Reviewed By: rafeca

Differential Revision: D7257022

fbshipit-source-id: 30598f2dd24a66bf07d75133ca10fb6b9082010a
This commit is contained in:
Jean Lauliac 2018-03-14 09:16:37 -07:00 committed by Facebook Github Bot
parent 167117fe36
commit 43ab7ab811
2 changed files with 63 additions and 20 deletions

View File

@ -60,7 +60,7 @@ it('can write then read a file as buffer', () => {
});
describe('createWriteStream', () => {
it('can write a file', done => {
it('writes a file', done => {
const st = fs.createWriteStream('/foo.txt');
let opened = false;
let closed = false;
@ -76,7 +76,7 @@ describe('createWriteStream', () => {
});
});
it('can write a file, as buffer', done => {
it('writes a file, as buffer', done => {
const st = fs.createWriteStream('/foo.txt');
let opened = false;
let closed = false;
@ -92,7 +92,7 @@ describe('createWriteStream', () => {
});
});
it('can write a file, with a starting position', done => {
it('writes a file, with a starting position', done => {
fs.writeFileSync('/foo.txt', 'test bar');
const st = fs.createWriteStream('/foo.txt', {start: 5, flags: 'r+'});
let opened = false;
@ -107,6 +107,22 @@ describe('createWriteStream', () => {
done();
});
});
it('writes a file with a custom fd', done => {
const fd = fs.openSync('/bar.txt', 'w');
const st = fs.createWriteStream('/foo.txt', {fd});
let opened = false;
let closed = false;
st.on('open', () => (opened = true));
st.on('close', () => (closed = true));
st.write('beep boop');
st.end(() => {
expect(opened).toBe(false);
expect(closed).toBe(true);
expect(fs.readFileSync('/bar.txt', 'utf8')).toEqual('beep boop');
done();
});
});
});
describe('createReadStream', () => {

View File

@ -482,22 +482,9 @@ class MemoryFs {
fd = this._open(pathStr(filePath), flags || 'w', mode);
process.nextTick(() => (st: any).emit('open', fd));
}
if (start != null) {
this._write(fd, new Buffer(0), 0, 0, start);
}
const ffd = fd;
const rst = new stream.Writable({
write: (buffer, encoding, callback) => {
try {
this._write(ffd, buffer, 0, buffer.length);
(st: any).bytesWritten += buffer.length;
} catch (error) {
callback(error);
return;
}
callback();
},
});
const ropt = {fd, writeSync: this._write.bind(this), filePath, start};
const rst = new WriteFileStream(ropt);
st = rst;
if (autoClose !== false) {
const doClose = () => {
@ -507,8 +494,6 @@ class MemoryFs {
rst.on('finish', doClose);
rst.on('error', doClose);
}
(st: any).path = filePath;
(st: any).bytesWritten = 0;
return st;
};
@ -811,6 +796,48 @@ class ReadFileSteam extends stream.Readable {
}
}
type WriteSync = (
fd: number,
buffer: Buffer,
offset: number,
length: number,
position?: number,
) => number;
class WriteFileStream extends stream.Writable {
bytesWritten: number;
path: string | Buffer;
_fd: number;
_writeSync: WriteSync;
constructor(opts: {
fd: number,
filePath: string | Buffer,
writeSync: WriteSync,
start: ?number,
}) {
super();
this.path = opts.filePath;
this.bytesWritten = 0;
this._fd = opts.fd;
this._writeSync = opts.writeSync;
if (opts.start != null) {
this._writeSync(opts.fd, new Buffer(0), 0, 0, opts.start);
}
}
_write(buffer, encoding, callback) {
try {
const bytesWritten = this._writeSync(this._fd, buffer, 0, buffer.length);
this.bytesWritten += bytesWritten;
} catch (error) {
callback(error);
return;
}
callback();
}
}
function checkPathLength(entNames, filePath) {
if (entNames.length > 32) {
throw makeError(