import { Activity, Answerable, AnswersQuestions, PerformsActivities, Task } from '@serenity-js/core'; import { formatted } from '@serenity-js/core/lib/io'; import { Expectation } from './Expectation'; import { ExpectationMet } from './outcomes'; export class Check extends Task { static whether(actual: Answerable, expectation: Expectation) { return { andIfSo: (...activities: Activity[]) => new Check(actual, expectation, activities), }; } constructor( private readonly actual: Answerable, private readonly expectation: Expectation, private readonly activities: Activity[], private readonly alternativeActivities: Activity[] = [], ) { super(); } otherwise(...alternativeActivities: Activity[]) { return new Check(this.actual, this.expectation, this.activities, alternativeActivities); } performAs(actor: AnswersQuestions & PerformsActivities): PromiseLike { return Promise.all([ actor.answer(this.actual), actor.answer(this.expectation), ]).then(([actual, expectation]) => expectation(actual).then(outcome => outcome instanceof ExpectationMet ? actor.attemptsTo(...this.activities) : actor.attemptsTo(...this.alternativeActivities), ), ); } toString(): string { return formatted `#actor ensures that ${ this.actual } does ${ this.expectation }`; } }