Skip to content
Permalink
Browse files
feat(assertions): new assertions library
affects: @serenity-js/assertions, @serenity-js/core
  • Loading branch information
jan-molak committed Jan 30, 2019
1 parent bd6fc90 commit 71b16eab5f88945253f2858ff8e6cebc2b3b8376
Showing with 842 additions and 554 deletions.
  1. +36 −117 packages/assertions/spec/Ensure.spec.ts
  2. +54 −0 packages/assertions/spec/assertions/Assertion.spec.ts
  3. +40 −0 packages/assertions/spec/assertions/and.spec.ts
  4. +30 −0 packages/assertions/spec/assertions/contains.spec.ts
  5. +0 −30 packages/assertions/spec/assertions/containsItem.spec.ts
  6. +0 −30 packages/assertions/spec/assertions/containsText.spec.ts
  7. +16 −16 packages/assertions/spec/assertions/endsWith.spec.ts
  8. +23 −28 packages/assertions/spec/assertions/equals.spec.ts
  9. +30 −0 packages/assertions/spec/assertions/includes.spec.ts
  10. +17 −17 packages/assertions/spec/assertions/isGreaterThan.spec.ts
  11. +16 −16 packages/assertions/spec/assertions/isLessThan.spec.ts
  12. +30 −0 packages/assertions/spec/assertions/matches.spec.ts
  13. +0 −30 packages/assertions/spec/assertions/matchesRegex.spec.ts
  14. +200 −15 packages/assertions/spec/assertions/not.spec.ts
  15. +40 −0 packages/assertions/spec/assertions/or.spec.ts
  16. +16 −16 packages/assertions/spec/assertions/startsWith.spec.ts
  17. +0 −73 packages/assertions/spec/values.spec.ts
  18. +0 −17 packages/assertions/src/Assertion.ts
  19. +15 −26 packages/assertions/src/Ensure.ts
  20. +55 −0 packages/assertions/src/assertions/Assertion.ts
  21. +25 −0 packages/assertions/src/assertions/and.ts
  22. +9 −0 packages/assertions/src/assertions/contains.ts
  23. +0 −19 packages/assertions/src/assertions/containsItem.ts
  24. +0 −18 packages/assertions/src/assertions/containsText.ts
  25. +4 −10 packages/assertions/src/assertions/endsWith.ts
  26. +5 −9 packages/assertions/src/assertions/equals.ts
  27. +8 −0 packages/assertions/src/assertions/includes.ts
  28. +7 −4 packages/assertions/src/assertions/index.ts
  29. +4 −10 packages/assertions/src/assertions/isGreaterThan.ts
  30. +4 −10 packages/assertions/src/assertions/isLessThan.ts
  31. +8 −0 packages/assertions/src/assertions/matches.ts
  32. +0 −18 packages/assertions/src/assertions/matchesRegex.ts
  33. +29 −9 packages/assertions/src/assertions/not.ts
  34. +54 −0 packages/assertions/src/assertions/or.ts
  35. +4 −10 packages/assertions/src/assertions/startsWith.ts
  36. +0 −2 packages/assertions/src/index.ts
  37. +40 −0 packages/core/spec/io/formatted.spec.ts
  38. +22 −4 packages/{assertions/src/values.ts → core/src/io/formatted.ts}
  39. +1 −0 packages/core/src/io/index.ts
@@ -1,132 +1,51 @@
import 'mocha';

import { expect } from '@integration/testing-tools';
import { Actor, AssertionError, Question } from '@serenity-js/core';
import { given } from 'mocha-testdata';

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

/** @test {Ensure} */
describe('Ensure', () => {

const Enrique = Actor.named('Enrique');
const p = value => Promise.resolve(value);
const q = value => Question.about(`the answer to some question`, actor => value);
const
Enrique = Actor.named('Enrique'),

it('is compatible with all the different permutations of the `KnowableUnknown` parameters', () => {
isIdenticalTo = <T>(expected: T) =>
Assertion.thatActualShould<T, T>('have value identical to', expected)
.soThat((actualValue: T, expectedValue: T) => actualValue === expectedValue),

const LastResult = () => Question.about<number>(`the result of the calculation`, (actor: Actor) => {
return 42;
});
p = <T>(value: T) => Promise.resolve(value),
q = <T>(value: T): Question<T> => Question.about(`something`, actor => value);

const LastPromisedResult = () => Question.about<Promise<number>>(`the result of the calculation`, (actor: Actor) => {
return Promise.resolve(42);
});

return Enrique.attemptsTo(
Ensure.that(42, equals(42)),
Ensure.that(Promise.resolve(42), equals(42)),
Ensure.that(LastResult(), equals(42)),
Ensure.that(LastPromisedResult(), equals(42)),
Ensure.that(42, equals(Promise.resolve(42))),
Ensure.that(Promise.resolve(42), equals(Promise.resolve(42))),
Ensure.that(LastResult(), equals(Promise.resolve(42))),
Ensure.that(LastPromisedResult(), equals(Promise.resolve(42))),
Ensure.that(42, equals(LastResult())),
Ensure.that(Promise.resolve(42), equals(LastResult())),
Ensure.that(LastResult(), equals(Promise.resolve(42))),
Ensure.that(LastPromisedResult(), equals(Promise.resolve(42))),
Ensure.that(42, equals(LastPromisedResult())),
Ensure.that(Promise.resolve(42), equals(LastPromisedResult())),
Ensure.that(LastResult(), equals(LastPromisedResult())),
Ensure.that(LastPromisedResult(), equals(LastPromisedResult())),
);
/** @test {Ensure.that} */
it('allows the actor to make an assertion', () => {
return expect(Enrique.attemptsTo(
Ensure.that(4, isIdenticalTo(4)),
)).to.be.fulfilled;
});

given([
{ description: `#actor ensures that 'a value' does equal 'a value'`, expected: 'a value', actual: 'a value' },
{ description: `#actor ensures that 'a value' does equal the promised value`, expected: p('a value'), actual: 'a value' },
{ description: `#actor ensures that 'a value' does equal the answer to some question`, expected: q('a value'), actual: 'a value' },
{ description: `#actor ensures that 'a value' does equal the answer to some question`, expected: q(p('a value')), actual: 'a value' },

{ description: `#actor ensures that the promised value does equal 'a value'`, expected: 'a value', actual: p('a value') },
{ description: `#actor ensures that the promised value does equal the promised value`, expected: p('a value'), actual: p('a value') },
{ description: `#actor ensures that the promised value does equal the answer to some question`, expected: q('a value'), actual: p('a value') },
{ description: `#actor ensures that the promised value does equal the answer to some question`, expected: q(p('a value')), actual: p('a value') },

{ description: `#actor ensures that the answer to some question does equal 'a value'`, expected: 'a value', actual: q('a value') },
{ description: `#actor ensures that the answer to some question does equal the promised value`, expected: p('a value'), actual: q('a value') },
{ description: `#actor ensures that the answer to some question does equal the answer to some question`, expected: q('a value'), actual: q('a value') },
{ description: `#actor ensures that the answer to some question does equal the answer to some question`, expected: q(p('a value')), actual: q('a value') },

{ description: `#actor ensures that the answer to some question does equal 'a value'`, expected: 'a value', actual: q(p('a value')) },
{ description: `#actor ensures that the answer to some question does equal the promised value`, expected: p('a value'), actual: q(p('a value')) },
{ description: `#actor ensures that the answer to some question does equal the answer to some question`, expected: q('a value'), actual: q(p('a value')) },
{ description: `#actor ensures that the answer to some question does equal the answer to some question`, expected: q(p('a value')), actual: q(p('a value')) },
]).
it('provides a task description based on the assertion given', ({ description, actual, expected }) => {
const task = Ensure.that(actual, equals(expected));

expect(task.toString()).to.equal(description);
/** @test {Ensure.that} */
it('fails the actor flow when the assertion is not met', () => {
return expect(Enrique.attemptsTo(
Ensure.that(4, isIdenticalTo(7)),
)).to.be.rejectedWith(AssertionError, 'Expected 4 to have value identical to 7');
});

given([
{ description: 'string, string', expected: 'a value', actual: 'a value' },
{ description: 'Promise<string>, string', expected: p('a value'), actual: 'a value' },
{ description: 'Question<string>, string', expected: q('a value'), actual: 'a value' },
{ description: 'Question<Promise<string>>, string', expected: q(p('a value')), actual: 'a value' },

{ description: 'string, Promise<string>', expected: 'a value', actual: p('a value') },
{ description: 'Promise<string>, Promise<string>', expected: p('a value'), actual: p('a value') },
{ description: 'Question<string>, Promise<string>', expected: q('a value'), actual: p('a value') },
{ description: 'Question<Promise<string>>, Promise<string>', expected: q(p('a value')), actual: p('a value') },

{ description: 'string, Question<string>', expected: 'a value', actual: q('a value') },
{ description: 'Promise<string>, Question<string>', expected: p('a value'), actual: q('a value') },
{ description: 'Question<string>, Question<string>', expected: q('a value'), actual: q('a value') },
{ description: 'Question<Promise<string>>, Question<string>', expected: q(p('a value')), actual: q('a value') },

{ description: 'string, Question<Promise<string>>', expected: 'a value', actual: q(p('a value')) },
{ description: 'Promise<string>, Question<Promise<string>>', expected: p('a value'), actual: q(p('a value')) },
{ description: 'Question<string>, Question<Promise<string>>', expected: q('a value'), actual: q(p('a value')) },
{ description: 'Question<Promise<string>>, Question<Promise<string>>', expected: q(p('a value')), actual: q(p('a value')) },
]).
it('returns a fulfilled promise when the assertion passes', ({ actual, expected }) =>
expect(Enrique.attemptsTo(
Ensure.that(actual, equals(expected)),
)).to.be.fulfilled, // ts-lint:disable-line:no-unused-expression
);

given([
{ description: `Expected 'actual' to equal 'expected'`, actual: 'actual', expected: 'expected' },
{ description: `Expected 'actual' to equal 'expected'`, actual: 'actual', expected: p('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: 'actual', expected: q('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: 'actual', expected: q(p('expected')) },

{ description: `Expected 'actual' to equal 'expected'`, actual: p('actual'), expected: 'expected' },
{ description: `Expected 'actual' to equal 'expected'`, actual: p('actual'), expected: p('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: p('actual'), expected: q('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: p('actual'), expected: q(p('expected')) },

{ description: `Expected 'actual' to equal 'expected'`, actual: q('actual'), expected: 'expected' },
{ description: `Expected 'actual' to equal 'expected'`, actual: q('actual'), expected: p('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: q('actual'), expected: q('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: q('actual'), expected: q(p('expected')) },

{ description: `Expected 'actual' to equal 'expected'`, actual: q(p('actual')), expected: 'expected' },
{ description: `Expected 'actual' to equal 'expected'`, actual: q(p('actual')), expected: p('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: q(p('actual')), expected: q('expected') },
{ description: `Expected 'actual' to equal 'expected'`, actual: q(p('actual')), expected: q(p('expected')) },
]).
it('rejects a promise when the assertion fails', ({ description, actual, expected }) =>
expect(Enrique.attemptsTo(
Ensure.that(actual, equals(expected)),
))
.to.be.rejectedWith(AssertionError, description)
.then(error => {
expect(error.expected).to.equal(expected);
expect(error.actual).to.equal(actual);
}),
);
/** @test {Ensure.that} */
it('provides a description of the assertion being made', () => {
expect(Ensure.that(4, isIdenticalTo(7)).toString()).to.equal(`#actor ensures that 4 does have value identical to 7`);
});

// todo add a stringification test [ Array(2) ]
given<KnowableUnknown<number>>(
42,
p(42),
q(42),
q(p(42)),
).
it('allows for the actual to be a KnowableUnknown<T> as it compares its value', (actual: KnowableUnknown<number>) => {
return expect(Enrique.attemptsTo(
Ensure.that(actual, isIdenticalTo(42)),
)).to.be.fulfilled;
});
});
@@ -0,0 +1,54 @@
import 'mocha';
import { given } from 'mocha-testdata';

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

/** @test {Assertion} */
describe('Assertion', () => {

const
Astrid = Actor.named('Astrid'),
p = <T>(value: T) => Promise.resolve(value),
q = <T>(value: T): Question<T> => Question.about(`something`, actor => value);

describe('allows to easily define an assertion, which', () => {

const isIdenticalTo = <T>(expected: T) =>
Assertion.thatActualShould<T, T>('have value identical to', expected)
.soThat((actualValue: T, expectedValue: T) => actualValue === expectedValue);

/**
* @test {Assertion.that}
* @test {Ensure.that}
*/
it('allows the actor flow to continue when the assertion passes', () => {
return expect(Astrid.attemptsTo(
Ensure.that(4, isIdenticalTo(4)),
)).to.be.fulfilled;
});

/**
* @test {Assertion.that}
* @test {Ensure.that}
*/
it('stops the actor flow when the assertion fails', () => {
return expect(Astrid.attemptsTo(
Ensure.that(4, isIdenticalTo('4' as any)),
)).to.be.rejectedWith(AssertionError, "Expected 4 to have value identical to '4'");
});

given<KnowableUnknown<number>>(
42,
p(42),
q(42),
q(p(42)),
).
it('allows for the expected value to be defined as any KnowableUnknown<T>', (expected: KnowableUnknown<number>) => {
return expect(Astrid.attemptsTo(
Ensure.that(42, isIdenticalTo(expected)),
)).to.be.fulfilled;
});
});
});
@@ -0,0 +1,40 @@
import 'mocha';

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

describe('and', () => {

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

/** @test {and} */
it(`allows for the actor flow to continue when the "actual" meets all the expectations`, () => {
return expect(Astrid.attemptsTo(
Ensure.that('Hello World!', and(startsWith('Hello'), endsWith('World!'))),
)).to.be.fulfilled;
});

describe(`breaks the actor flow when "actual"`, () => {

/** @test {and} */
it(`does not meet the first expectation`, () => {
return expect(Astrid.attemptsTo(
Ensure.that('Hello World!', and(startsWith('¡Hola'), endsWith('World!'))),
)).to.be.rejectedWith(AssertionError, `Expected 'Hello World!' to start with '¡Hola'`);
});

/** @test {and} */
it(`does not meet the second expectation`, () => {
return expect(Astrid.attemptsTo(
Ensure.that('Hello World!', and(startsWith('Hello'), endsWith('Mundo!'))),
)).to.be.rejectedWith(AssertionError, `Expected 'Hello World!' to end with 'Mundo!`);
});
});

/** @test {and} */
it(`contributes to a human-readable description`, () => {
expect(Ensure.that('Hello', and(startsWith('H'), endsWith('o'))).toString())
.to.equal(`#actor ensures that 'Hello' does start with 'H' and end with 'o'`);
});
});
@@ -0,0 +1,30 @@
import 'mocha';

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

describe('contains', () => {

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

/** @test {contains} */
it(`allows for the actor flow to continue when the "actual" contains the "expected" text`, () => {
return expect(Astrid.attemptsTo(
Ensure.that([ { word: 'Hello' }, { word: 'World' } ], contains({ word: 'World' })),
)).to.be.fulfilled;
});

/** @test {contains} */
it(`breaks the actor flow when "actual" does not contain the "expected" text`, () => {
return expect(Astrid.attemptsTo(
Ensure.that([ 'Hello', 'World' ], contains('Mundo')),
)).to.be.rejectedWith(AssertionError, `Expected [ 'Hello', 'World' ] to contain 'Mundo'`);
});

/** @test {contains} */
it(`contributes to a human-readable description`, () => {
expect(Ensure.that([ 1, 2, 3 ], contains(2)).toString())
.to.equal(`#actor ensures that [ 1, 2, 3 ] does contain 2`);
});
});

This file was deleted.

This file was deleted.

0 comments on commit 71b16ea

Please sign in to comment.