src/expectations/containAtLeastOneItemThat.ts
import { AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
import { formatted } from '@serenity-js/core/lib/io';
export function containAtLeastOneItemThat<Actual>(expectation: Expectation<any, Actual>): Expectation<any, Actual[]> {
return new ContainAtLeastOneItemThatMeetsExpectation(expectation);
}
class ContainAtLeastOneItemThatMeetsExpectation<Expected, Actual> extends Expectation<Expected, Actual[]> {
constructor(private readonly expectation: Expectation<Expected, Actual>) {
super(formatted `contain at least one item that does ${ expectation }`);
}
answeredBy(actor: AnswersQuestions): (actual: Actual[]) => Promise<ExpectationOutcome<Expected, Actual[]>> {
return (actual: Actual[]) =>
actual.length === 0
? Promise.resolve(new ExpectationNotMet(this.toString(), undefined, actual))
: Promise.all(actual.map(item => this.expectation.answeredBy(actor)(item)))
.then(results => results.some(result => result instanceof ExpectationMet)
? new ExpectationMet(this.toString(), results[0].expected, actual)
: new ExpectationNotMet(this.toString(), results[0].expected, actual),
);
}
}