Skip to content
Merged
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
7 changes: 4 additions & 3 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ export namespace Team {
*
* @default 1
*/
readonly meetings?: number;
readonly meetings?: number | undefined;

/**
* Throws when the team attends more than the expected number of `meetings`.
* Throws when the team attends more than the expected number of `meetings`,
* or if scheduling an empty meeting.
*
* @default false
*/
readonly strict?: boolean;
readonly strict?: boolean | undefined;
}

type ElementOf<T> = T extends (infer E)[] ? E : T;
Expand Down
47 changes: 35 additions & 12 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,52 @@ exports.Team = class {
this._reject = reject;
});

const meetings = options.meetings || 1;
const meetings = options.meetings ?? 1;
const strict = !!options.strict;

if (!Number.isInteger(meetings) || meetings <= 0) {
if (meetings === 0 && !strict) {
return this._finalize(null, null);
}

throw new Error('Invalid meetings value');
}

this.#meetings = meetings;
this.#count = meetings;
this.#notes = [];
this.#done = false;
this.#strict = options.strict;
this.#strict = strict;

}

attend(note) {
_finalize(err, note) {

if (this.#strict && this.#done) {
throw new Error('Unscheduled meeting');
this.#done = true;
this.#notes = null;

if (err) {
this._reject(err);
}
else if (this.#done) {
else {
this._resolve(note);
}
}

attend(note) {

if (this.#done) {
if (this.#strict) {
throw new Error('Unscheduled meeting');
}

// else ignore

return;
}

if (note instanceof Error) {
this.#done = true;
this.#notes = null;
return this._reject(note);
return this._finalize(note);
}

this.#notes.push(note);
Expand All @@ -58,9 +83,7 @@ exports.Team = class {
return;
}

this.#done = true;
this._resolve(this.#meetings === 1 ? this.#notes[0] : [...this.#notes]);
this.#notes = null;
this._finalize(null, this.#meetings === 1 ? this.#notes[0] : this.#notes);
}

async regroup(options) {
Expand Down
17 changes: 17 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,23 @@ describe('Team', () => {
expect(Teamwork.Team._notes(team)).to.be.null();
});

it('immediately resolves non-strict empty meetings with null', async () => {

const team = new Teamwork.Team({ meetings: 0, strict: false });

const notes = await team.work;
expect(notes).to.equal(null);
});

it('throws error on invalid meetings', () => {

expect(() => new Teamwork.Team({ meetings: 0, strict: true })).to.throw('Invalid meetings value');
expect(() => new Teamwork.Team({ meetings: 0.5 })).to.throw('Invalid meetings value');
expect(() => new Teamwork.Team({ meetings: -1 })).to.throw('Invalid meetings value');
expect(() => new Teamwork.Team({ meetings: NaN })).to.throw('Invalid meetings value');
expect(() => new Teamwork.Team({ meetings: '' })).to.throw('Invalid meetings value');
});

it('regroup works after team error', async () => {

const team = new Teamwork.Team({ meetings: 2, strict: true });
Expand Down
Loading