Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

breaking: end on read (part 1) #45

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
174 changes: 80 additions & 94 deletions asynciterator.ts

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"c8": "^7.2.0",
"chai": "^4.2.0",
"eslint": "^5.16.0",
"event-emitter-promisify": "^1.1.0",
"husky": "^4.2.5",
"jaguarjs-jsdoc": "^1.1.0",
"jsdoc": "^3.5.5",
Expand Down
204 changes: 196 additions & 8 deletions test/ArrayIterator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import {
} from '../dist/asynciterator.js';

import { EventEmitter } from 'events';
import { promisifyEventEmitter } from 'event-emitter-promisify';

describe('ArrayIterator', () => {
describe('The ArrayIterator function', () => {
describe('the result when called with `new`', () => {
let instance;
before(() => { instance = new ArrayIterator(); });
before(() => { instance = new ArrayIterator([]); });

it('should be an ArrayIterator object', () => {
instance.should.be.an.instanceof(ArrayIterator);
Expand All @@ -27,7 +28,7 @@ describe('ArrayIterator', () => {

describe('the result when called through `fromArray`', () => {
let instance;
before(() => { instance = fromArray(); });
before(() => { instance = fromArray([]); });

it('should be an ArrayIterator object', () => {
instance.should.be.an.instanceof(ArrayIterator);
Expand All @@ -46,16 +47,25 @@ describe('ArrayIterator', () => {
describe('An ArrayIterator without arguments', () => {
let iterator;
before(() => {
iterator = new ArrayIterator();
iterator = new ArrayIterator([]);
captureEvents(iterator, 'readable', 'end');
});

it('should provide a readable `toString` representation', () => {
iterator.toString().should.equal('[ArrayIterator (0)]');
});

it('should not have emitted the `readable` event', () => {
iterator._eventCounts.readable.should.equal(0);
it('should have emitted the `readable` event', () => {
iterator._eventCounts.readable.should.equal(1);
});

it('should not have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(0);
});

it('emit end once data is subscribed', done => {
iterator.on('end', done);
iterator.on('data', () => { throw new Error('should not emit data'); });
});

it('should have emitted the `end` event', () => {
Expand Down Expand Up @@ -95,7 +105,16 @@ describe('ArrayIterator', () => {
});

it('should not have emitted the `readable` event', () => {
iterator._eventCounts.readable.should.equal(0);
iterator._eventCounts.readable.should.equal(1);
});

it('should not have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(0);
});

it('emit end once data is subscribed', done => {
iterator.on('data', () => { throw new Error('should not emit data'); });
iterator.on('end', done);
});

it('should have emitted the `end` event', () => {
Expand Down Expand Up @@ -127,10 +146,127 @@ describe('ArrayIterator', () => {
});
});

describe('An ArrayIterator with an empty array without autoStart', () => {
describe('An ArrayIterator with an empty array (no use of flow)', () => {
let iterator;
before(() => {
iterator = new ArrayIterator([], { autoStart: false });
iterator = new ArrayIterator([]);
captureEvents(iterator, 'readable', 'end');
});

it('should provide a readable `toString` representation', () => {
iterator.toString().should.equal('[ArrayIterator (0)]');
});

it('should not have emitted the `readable` event', () => {
iterator._eventCounts.readable.should.equal(1);
});

it('should not have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(0);
});

it('should return null when read is called', () => {
expect(iterator.read()).to.be.null;
});

it('should have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(1);
});

it('should have ended', () => {
iterator.ended.should.be.true;
});

it('should not have been destroyed', () => {
iterator.destroyed.should.be.false;
});

it('should be done', () => {
iterator.done.should.be.true;
});

it('should not be readable', () => {
iterator.readable.should.be.false;
});

it('should return null when read is called', () => {
expect(iterator.read()).to.be.null;
});

it('should return null when read is called', () => {
expect(iterator.read()).to.be.null;
});
});


describe('An ArrayIterator with an array [1] (no use of flow)', () => {
let iterator;
before(() => {
iterator = new ArrayIterator([1]);
captureEvents(iterator, 'readable', 'end');
});

it('should provide a readable `toString` representation', () => {
iterator.toString().should.equal('[ArrayIterator (1)]');
});

it('should not have emitted the `readable` event', () => {
iterator._eventCounts.readable.should.equal(1);
});

it('should not have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(0);
});

it('should return 1 when read is called', () => {
expect(iterator.read()).to.equal(1);
});

it('should not have emitted the `readable` event', () => {
iterator._eventCounts.readable.should.equal(1);
});

it('should not have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(0);
});

it('should return null when read is called', () => {
expect(iterator.read()).to.be.null;
});

it('should have emitted the `end` event', () => {
iterator._eventCounts.end.should.equal(1);
});

it('should have ended', () => {
iterator.ended.should.be.true;
});

it('should not have been destroyed', () => {
iterator.destroyed.should.be.false;
});

it('should be done', () => {
iterator.done.should.be.true;
});

it('should not be readable', () => {
iterator.readable.should.be.false;
});

it('should return null when read is called', () => {
expect(iterator.read()).to.be.null;
});

it('should return null when read is called', () => {
expect(iterator.read()).to.be.null;
});
});

describe('An ArrayIterator with an empty array', () => {
let iterator;
before(() => {
iterator = new ArrayIterator([]);
captureEvents(iterator, 'readable', 'end');
});

Expand Down Expand Up @@ -679,4 +815,56 @@ describe('ArrayIterator', () => {
});
});
});

describe('A ArrayIterator with no elements should not emit until read from', () => {
it('awaiting undefined (with empty array)', async () => {
const iterator = new ArrayIterator([]);
await undefined;
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});

it('awaiting promise (with empty array)', async () => {
const iterator = new ArrayIterator([]);
await Promise.resolve();
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});

it('awaiting undefined (with one element)', async () => {
const iterator = new ArrayIterator([1]);
await undefined;
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});

it('awaiting promise (with one element)', async () => {
const iterator = new ArrayIterator([1]);
await Promise.resolve();
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});
});

describe('An ArrayIterator with no elements should not emit until read from (fromArray constructor)', () => {
it('awaiting undefined (with empty array)', async () => {
const iterator = fromArray([]);
await undefined;
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});

it('awaiting promise (with empty array)', async () => {
const iterator = fromArray([]);
await Promise.resolve();
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});

it('awaiting undefined (with one element)', async () => {
const iterator = fromArray([1]);
await undefined;
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});

it('awaiting promise (with one element)', async () => {
const iterator = fromArray([1]);
await Promise.resolve();
await expect(await promisifyEventEmitter(iterator.on('data', () => { /* */ }))).to.be.undefined;
});
});
});
Loading