import { AnswersQuestions } from '@serenity-js/core'; import { Expectation } from '../Expectation'; import { ExpectationMet, ExpectationNotMet, Outcome } from '../outcomes'; export function or(...assertions: Array>): Expectation { return new Or(assertions); } /** * @package */ class Or extends Expectation { private static readonly Separator = ' or '; constructor(private readonly expectations: Array>) { super(); } answeredBy(actor: AnswersQuestions): (actual: Actual) => Promise> { return (actual: any) => this.expectations.reduce( (previous, current) => previous.then((outcomesSoFar: Array>) => current.answeredBy(actor)(actual) .then(outcome => outcomesSoFar.concat(outcome)), // todo: should stop on the first met expectation ), Promise.resolve([]), ). then((outcomes: Array>) => { const unmetExpectations = outcomes.filter(outcome => outcome instanceof ExpectationNotMet), message = outcomes.map(outcome => outcome.message).join(Or.Separator); return unmetExpectations.length === this.expectations.length ? new ExpectationNotMet(message, outcomes[0].expected, outcomes[0].actual) : new ExpectationMet(message, outcomes[0].expected, outcomes[0].actual); }); } toString(): string { return this.expectations .map(assertion => assertion.toString()) .join(Or.Separator); } }