Skip to content
Permalink
Browse files
feat(assertions): isBefore, isAfter and containItemsWhereEachItem exp…
…ectations
  • Loading branch information
jan-molak committed Mar 13, 2019
1 parent 686c6e8 commit db6e46566f017097d8ad81b47809bcdb835fb266
@@ -0,0 +1,39 @@
import 'mocha';

import { expect } from '@integration/testing-tools';
import { Actor, AssertionError, Question } from '@serenity-js/core';
import { containItemsWhereEachItem, Ensure, equals, isGreaterThan } from '../../src';

describe('containItemsWhereEachItem', () => {

const Astrid = Actor.named('Astrid');

/** @test {containItemsWhereEachItem} */
it(`allows for the actor flow to continue when the "actual" includes only those items that meet the expectation`, () => {
return Astrid.attemptsTo(
Ensure.that([ 1, 2, 3 ], containItemsWhereEachItem(isGreaterThan(0))),
);
});

/** @test {containItemsWhereEachItem} */
it(`breaks the actor flow when "actual" contains at least one item that does not meet the expectation`, () => {
return expect(Astrid.attemptsTo(
Ensure.that([ 7, 7, 2 ], containItemsWhereEachItem(equals(7))),
)).to.be.rejectedWith(AssertionError, `Expected [ 7, 7, 2 ] to contain items where each item does equal 7`);
});

/** @test {containItemsWhereEachItem} */
it(`breaks the actor flow when "actual" is an empty list`, () => {
return expect(Astrid.attemptsTo(
Ensure.that([], containItemsWhereEachItem(equals(42))),
)).to.be.rejectedWith(AssertionError, `Expected [ ] to contain items where each item does equal 42`);
});

/** @test {atLeastOne} */
it(`contributes to a human-readable description`, () => {
const numbers = () => Question.about('list of numbers', actor => [ 0, 1, 2 ]);

expect(Ensure.that(numbers(), containItemsWhereEachItem(isGreaterThan(1))).toString())
.to.equal(`#actor ensures that list of numbers does contain items where each item does have value greater than 1`);
});
});
@@ -0,0 +1,30 @@
import 'mocha';

import { expect } from '@integration/testing-tools';
import { Actor, AssertionError } from '@serenity-js/core';
import { Ensure, isAfter } from '../../src';

describe('isAfter', () => {

const Astrid = Actor.named('Astrid');

/** @test {isAfter} */
it(`allows for the actor flow to continue when the "actual" is after the "expected"`, () => {
return expect(Astrid.attemptsTo(
Ensure.that(new Date('1995-01-01'), isAfter(new Date('1985-01-01'))),
)).to.be.fulfilled;
});

/** @test {isAfter} */
it(`breaks the actor flow when "actual" is not after the "expected"`, () => {
return expect(Astrid.attemptsTo(
Ensure.that(new Date('1985-01-01'), isAfter(new Date('1995-01-01'))),
)).to.be.rejectedWith(AssertionError, `Expected 1985-01-01T00:00:00.000Z to have value that is after 1995-01-01T00:00:00.000Z`);
});

/** @test {isAfter} */
it(`contributes to a human-readable description`, () => {
expect(Ensure.that(new Date('1995-01-01'), isAfter(new Date('1985-01-01'))).toString())
.to.equal(`#actor ensures that 1995-01-01T00:00:00.000Z does have value that is after 1985-01-01T00:00:00.000Z`);
});
});
@@ -0,0 +1,30 @@
import 'mocha';

import { expect } from '@integration/testing-tools';
import { Actor, AssertionError } from '@serenity-js/core';
import { Ensure, isBefore } from '../../src';

describe('isBefore', () => {

const Astrid = Actor.named('Astrid');

/** @test {isBefore} */
it(`allows for the actor flow to continue when the "actual" is before the "expected"`, () => {
return expect(Astrid.attemptsTo(
Ensure.that(new Date('1985-01-01'), isBefore(new Date('1995-01-01'))),
)).to.be.fulfilled;
});

/** @test {isBefore} */
it(`breaks the actor flow when "actual" is not before the "expected"`, () => {
return expect(Astrid.attemptsTo(
Ensure.that(new Date('1995-01-01'), isBefore(new Date('1985-01-01'))),
)).to.be.rejectedWith(AssertionError, `Expected 1995-01-01T00:00:00.000Z to have value that is before 1985-01-01T00:00:00.000Z`);
});

/** @test {isBefore} */
it(`contributes to a human-readable description`, () => {
expect(Ensure.that(new Date('1985-01-01'), isBefore(new Date('1995-01-01'))).toString())
.to.equal(`#actor ensures that 1985-01-01T00:00:00.000Z does have value that is before 1995-01-01T00:00:00.000Z`);
});
});
@@ -11,6 +11,7 @@ class ContainAtLeastOneItemThatMeetsExpectation<Expected, Actual> extends Expect
constructor(private readonly expectation: Expectation<Expected, Actual>) {
super();
}

answeredBy(actor: AnswersQuestions): (actual: Actual[]) => Promise<Outcome<Expected, Actual[]>> {
return (actual: Actual[]) =>
actual.length === 0
@@ -0,0 +1,29 @@
import { AnswersQuestions } from '@serenity-js/core';
import { formatted } from '@serenity-js/core/lib/io';
import { Expectation } from '../Expectation';
import { ExpectationMet, ExpectationNotMet, Outcome } from '../outcomes';

export function containItemsWhereEachItem<Actual>(expectation: Expectation<any, Actual>): Expectation<any, Actual[]> {
return new ContainItemsWhereEachItemMeetsExpectation(expectation);
}

class ContainItemsWhereEachItemMeetsExpectation<Expected, Actual> extends Expectation<Expected, Actual[]> {
constructor(private readonly expectation: Expectation<Expected, Actual>) {
super();
}

answeredBy(actor: AnswersQuestions): (actual: Actual[]) => Promise<Outcome<Expected, Actual[]>> {
return (actual: Actual[]) =>
actual.length === 0
? Promise.resolve(new ExpectationNotMet(this.toString(), null, actual))
: Promise.all(actual.map(item => this.expectation.answeredBy(actor)(item)))
.then(results => results.every(result => result instanceof ExpectationMet)
? new ExpectationMet(this.toString(), results[0].expected, actual)
: new ExpectationNotMet(this.toString(), results[0].expected, actual),
);
}

toString(): string {
return formatted `contain items where each item does ${ this.expectation }`;
}
}
@@ -1,9 +1,12 @@
export * from './and';
export * from './contains';
export * from './containAtLeastOneItemThat';
export * from './containItemsWhereEachItem';
export * from './endsWith';
export * from './equals';
export * from './includes';
export * from './isAfter';
export * from './isBefore';
export * from './isGreaterThan';
export * from './isLessThan';
export * from './matches';
@@ -0,0 +1,8 @@
import { KnowableUnknown } from '@serenity-js/core';

import { Expectation } from '../Expectation';

export function isAfter(expected: KnowableUnknown<Date>): Expectation<Date> {
return Expectation.thatActualShould<Date, Date>('have value that is after', expected)
.soThat((actualValue, expectedValue) => actualValue.getTime() > expectedValue.getTime());
}
@@ -0,0 +1,8 @@
import { KnowableUnknown } from '@serenity-js/core';

import { Expectation } from '../Expectation';

export function isBefore(expected: KnowableUnknown<Date>): Expectation<Date> {
return Expectation.thatActualShould<Date, Date>('have value that is before', expected)
.soThat((actualValue, expectedValue) => actualValue.getTime() < expectedValue.getTime());
}

0 comments on commit db6e465

Please sign in to comment.