Skip to content

Commit

Permalink
fix(fs.walk): do not destroy reader when it is already destroyed
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmlnc committed Dec 26, 2020
1 parent d672a09 commit b007c63
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
15 changes: 14 additions & 1 deletion packages/fs/fs.walk/src/providers/stream.spec.ts
Expand Up @@ -10,10 +10,12 @@ import StreamProvider from './stream';

class TestProvider extends StreamProvider {
protected readonly _reader: AsyncReader = new tests.TestAsyncReader() as unknown as AsyncReader;
protected readonly _stream: Readable = sinon.createStubInstance(Readable) as unknown as Readable;

constructor(_root: string, _settings: Settings = new Settings()) {
super(_root, _settings);

this._stream.emit = sinon.stub();
this._stream.push = sinon.stub();
}

public get reader(): tests.TestAsyncReader {
Expand Down Expand Up @@ -73,5 +75,16 @@ describe('Providers → Stream', () => {

assert.deepStrictEqual(provider.stream.push.args, [[null]]);
});

it('should do not destroy reader when it is already destroyed', () =>{
const provider = new TestProvider('directory');

const stream = provider.read();

stream.destroy();

assert.ok(stream.destroyed);
assert.doesNotThrow(() => stream.destroy());
});
});
});
6 changes: 5 additions & 1 deletion packages/fs/fs.walk/src/providers/stream.ts
Expand Up @@ -7,7 +7,11 @@ export default class StreamProvider {
protected readonly _stream: Readable = new Readable({
objectMode: true,
read: () => { /* noop */ },
destroy: this._reader.destroy.bind(this._reader)
destroy: () => {
if (!this._reader.isDestroyed) {
this._reader.destroy();
}
}
});

constructor(private readonly _root: string, private readonly _settings: Settings) { }
Expand Down
8 changes: 8 additions & 0 deletions packages/fs/fs.walk/src/readers/async.spec.ts
Expand Up @@ -211,6 +211,14 @@ describe('Readers → Async', () => {
reader.read();
});

it('should mark stream as "destroyed" after first destroy', () => {
const reader = new TestReader('directory');

reader.destroy();

assert.ok(reader.isDestroyed);
});

it('should throw an error when trying to destroy reader twice', () => {
const reader = new TestReader('directory');

Expand Down
4 changes: 4 additions & 0 deletions packages/fs/fs.walk/src/readers/async.ts
Expand Up @@ -41,6 +41,10 @@ export default class AsyncReader extends Reader {
return this._emitter;
}

public get isDestroyed(): boolean {
return this._isDestroyed;
}

public destroy(): void {
if (this._isDestroyed) {
throw new Error('The reader is already destroyed');
Expand Down

0 comments on commit b007c63

Please sign in to comment.