@serenity-js/assertions 3.0.0-rc.2 → 3.0.0-rc.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +480 -1
  2. package/README.md +1 -1
  3. package/lib/Ensure.d.ts +1 -1
  4. package/lib/Ensure.js +7 -10
  5. package/lib/Ensure.js.map +1 -1
  6. package/lib/expectations/and.d.ts +1 -1
  7. package/lib/expectations/and.js +6 -6
  8. package/lib/expectations/and.js.map +1 -1
  9. package/lib/expectations/contain.d.ts +1 -1
  10. package/lib/expectations/containAtLeastOneItemThat.d.ts +1 -1
  11. package/lib/expectations/containAtLeastOneItemThat.js +16 -9
  12. package/lib/expectations/containAtLeastOneItemThat.js.map +1 -1
  13. package/lib/expectations/containItemsWhereEachItem.d.ts +1 -1
  14. package/lib/expectations/containItemsWhereEachItem.js +16 -9
  15. package/lib/expectations/containItemsWhereEachItem.js.map +1 -1
  16. package/lib/expectations/index.d.ts +2 -1
  17. package/lib/expectations/index.js +7 -2
  18. package/lib/expectations/index.js.map +1 -1
  19. package/lib/expectations/isCloseTo.d.ts +17 -0
  20. package/lib/expectations/isCloseTo.js +51 -0
  21. package/lib/expectations/isCloseTo.js.map +1 -0
  22. package/lib/expectations/isFalse.js.map +1 -1
  23. package/lib/expectations/isPresent.d.ts +14 -0
  24. package/lib/expectations/isPresent.js +50 -0
  25. package/lib/expectations/isPresent.js.map +1 -0
  26. package/lib/expectations/isTrue.js.map +1 -1
  27. package/lib/expectations/matches.d.ts +1 -1
  28. package/lib/expectations/not.d.ts +1 -1
  29. package/lib/expectations/not.js +7 -8
  30. package/lib/expectations/not.js.map +1 -1
  31. package/lib/expectations/or.d.ts +1 -1
  32. package/lib/expectations/or.js +17 -12
  33. package/lib/expectations/or.js.map +1 -1
  34. package/lib/index.js +5 -1
  35. package/lib/index.js.map +1 -1
  36. package/package.json +12 -33
  37. package/src/Ensure.ts +17 -21
  38. package/src/expectations/and.ts +19 -18
  39. package/src/expectations/contain.ts +1 -1
  40. package/src/expectations/containAtLeastOneItemThat.ts +38 -14
  41. package/src/expectations/containItemsWhereEachItem.ts +38 -14
  42. package/src/expectations/index.ts +2 -1
  43. package/src/expectations/isCloseTo.ts +60 -0
  44. package/src/expectations/isFalse.ts +1 -1
  45. package/src/expectations/isPresent.ts +58 -0
  46. package/src/expectations/isTrue.ts +1 -1
  47. package/src/expectations/matches.ts +1 -1
  48. package/src/expectations/not.ts +15 -15
  49. package/src/expectations/or.ts +28 -25
  50. package/lib/expectations/property.d.ts +0 -2
  51. package/lib/expectations/property.js +0 -28
  52. package/lib/expectations/property.js.map +0 -1
  53. package/src/expectations/property.ts +0 -33
@@ -1,29 +1,30 @@
1
- import { AnswersQuestions, Expectation, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
1
+ import { Answerable, AnswersQuestions, Expectation, ExpectationNotMet } from '@serenity-js/core';
2
2
  import { match } from 'tiny-types';
3
3
 
4
- export function and<Actual>(...expectations: Array<Expectation<any, Actual>>): Expectation<any, Actual> {
4
+ export function and<Actual>(...expectations: Array<Expectation<Actual>>): Expectation<Actual> {
5
5
  return new And(expectations);
6
6
  }
7
7
 
8
8
  /**
9
9
  * @package
10
10
  */
11
- class And<Actual> extends Expectation<any, Actual> {
12
- constructor(private readonly expectations: Array<Expectation<any, Actual>>) {
13
- super(expectations.map(assertion => assertion.toString()).join(' and '));
14
- }
15
-
16
- answeredBy(actor: AnswersQuestions): (actual: Actual) => Promise<ExpectationOutcome<any, Actual>> {
11
+ class And<Actual> extends Expectation<Actual> {
12
+ private static readonly Separator = ' and ';
17
13
 
18
- return (actual: any) =>
19
- this.expectations.reduce(
20
- (previous, current) =>
21
- previous.then(outcome =>
22
- match(outcome)
23
- .when(ExpectationNotMet, o => o)
24
- .else(_ => current.answeredBy(actor)(actual)),
25
- ),
26
- Promise.resolve(void 0),
27
- );
14
+ constructor(private readonly expectations: Array<Expectation<Actual>>) {
15
+ super(
16
+ expectations.map(expectation => expectation.toString()).join(And.Separator),
17
+ (actor: AnswersQuestions, actual: Answerable<Actual>) => {
18
+ return expectations.reduce(
19
+ (previous, current) =>
20
+ previous.then(outcome =>
21
+ match(outcome)
22
+ .when(ExpectationNotMet, o => o)
23
+ .else(_ => actor.answer(current.isMetFor(actual))),
24
+ ),
25
+ Promise.resolve(void 0),
26
+ );
27
+ }
28
+ );
28
29
  }
29
30
  }
@@ -1,7 +1,7 @@
1
1
  import { Answerable, Expectation } from '@serenity-js/core';
2
2
  import { equal } from 'tiny-types/lib/objects';
3
3
 
4
- export function contain<Item>(expected: Answerable<Item>): Expectation<Item, Item[]> {
4
+ export function contain<Item>(expected: Answerable<Item>): Expectation<Item[]> {
5
5
  return Expectation.thatActualShould<Item, Item[]>('contain', expected)
6
6
  .soThat((actualValue, expectedValue) => !! ~ actualValue.findIndex(av => equal(av, expectedValue)));
7
7
  }
@@ -1,26 +1,50 @@
1
- import { AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
2
- import { formatted } from '@serenity-js/core/lib/io';
1
+ import { Answerable, AnswersQuestions, d, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
3
2
 
4
- export function containAtLeastOneItemThat<Actual>(expectation: Expectation<any, Actual>): Expectation<any, Actual[]> {
3
+ export function containAtLeastOneItemThat<Actual>(expectation: Expectation<Actual>): Expectation<Actual[]> {
5
4
  return new ContainAtLeastOneItemThatMeetsExpectation(expectation);
6
5
  }
7
6
 
8
7
  /**
9
8
  * @package
10
9
  */
11
- class ContainAtLeastOneItemThatMeetsExpectation<Expected, Actual> extends Expectation<Expected, Actual[]> {
12
- constructor(private readonly expectation: Expectation<Expected, Actual>) {
13
- super(formatted `contain at least one item that does ${ expectation }`);
10
+ class ContainAtLeastOneItemThatMeetsExpectation<Actual> extends Expectation<Actual[]> {
11
+
12
+ private static descriptionFor(expectation: Expectation<any>) {
13
+ return d`contain at least one item that does ${ expectation }`;
14
14
  }
15
15
 
16
- answeredBy(actor: AnswersQuestions): (actual: Actual[]) => Promise<ExpectationOutcome<Expected, Actual[]>> {
17
- return (actual: Actual[]) =>
18
- actual.length === 0
19
- ? Promise.resolve(new ExpectationNotMet(this.toString(), undefined, actual))
20
- : Promise.all(actual.map(item => this.expectation.answeredBy(actor)(item)))
21
- .then(results => results.some(result => result instanceof ExpectationMet)
22
- ? new ExpectationMet(this.toString(), results[0].expected, actual)
23
- : new ExpectationNotMet(this.toString(), results[0].expected, actual),
16
+ constructor(private readonly expectation: Expectation<Actual>) {
17
+ super(
18
+ ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation),
19
+ async (actor: AnswersQuestions, actual: Answerable<Actual[]>) => {
20
+
21
+ const items: Actual[] = await actor.answer(actual);
22
+
23
+ if (! items || items.length === 0) {
24
+ return new ExpectationNotMet(
25
+ ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation),
26
+ undefined,
27
+ items,
24
28
  );
29
+ }
30
+
31
+ let outcome: ExpectationOutcome<unknown, Actual>;
32
+
33
+ for (const item of items) {
34
+
35
+ outcome = await actor.answer(expectation.isMetFor(item))
36
+
37
+ if (outcome instanceof ExpectationMet) {
38
+ return new ExpectationMet(
39
+ ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation),
40
+ outcome.expected,
41
+ items
42
+ );
43
+ }
44
+ }
45
+
46
+ return new ExpectationNotMet(ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation), outcome.expected, items);
47
+ }
48
+ );
25
49
  }
26
50
  }
@@ -1,26 +1,50 @@
1
- import { AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
2
- import { formatted } from '@serenity-js/core/lib/io';
1
+ import { Answerable, AnswersQuestions, d, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
3
2
 
4
- export function containItemsWhereEachItem<Actual>(expectation: Expectation<any, Actual>): Expectation<any, Actual[]> {
3
+ export function containItemsWhereEachItem<Actual>(expectation: Expectation<Actual>): Expectation<Actual[]> {
5
4
  return new ContainItemsWhereEachItemMeetsExpectation(expectation);
6
5
  }
7
6
 
8
7
  /**
9
8
  * @package
10
9
  */
11
- class ContainItemsWhereEachItemMeetsExpectation<Expected, Actual> extends Expectation<Expected, Actual[]> {
12
- constructor(private readonly expectation: Expectation<Expected, Actual>) {
13
- super(formatted `contain items where each item does ${ expectation }`);
10
+ class ContainItemsWhereEachItemMeetsExpectation<Actual> extends Expectation<Actual[]> {
11
+
12
+ private static descriptionFor(expectation: Expectation<any>) {
13
+ return d`contain items where each item does ${ expectation }`;
14
14
  }
15
15
 
16
- answeredBy(actor: AnswersQuestions): (actual: Actual[]) => Promise<ExpectationOutcome<Expected, Actual[]>> {
17
- return (actual: Actual[]) =>
18
- actual.length === 0
19
- ? Promise.resolve(new ExpectationNotMet(this.toString(), undefined, actual))
20
- : Promise.all(actual.map(item => this.expectation.answeredBy(actor)(item)))
21
- .then(results => results.every(result => result instanceof ExpectationMet)
22
- ? new ExpectationMet(this.toString(), results[0].expected, actual)
23
- : new ExpectationNotMet(this.toString(), results[0].expected, actual),
16
+ constructor(private readonly expectation: Expectation<Actual>) {
17
+ super(
18
+ ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation),
19
+ async (actor: AnswersQuestions, actual: Answerable<Actual[]>) => {
20
+
21
+ const items: Actual[] = await actor.answer(actual);
22
+
23
+ if (! items || items.length === 0) {
24
+ return new ExpectationNotMet(
25
+ ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation),
26
+ undefined,
27
+ items,
24
28
  );
29
+ }
30
+
31
+ let outcome: ExpectationOutcome<unknown, Actual>;
32
+
33
+ for (const item of items) {
34
+
35
+ outcome = await actor.answer(expectation.isMetFor(item))
36
+
37
+ if (outcome instanceof ExpectationNotMet) {
38
+ return new ExpectationNotMet(
39
+ ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation),
40
+ outcome.expected,
41
+ items
42
+ );
43
+ }
44
+ }
45
+
46
+ return new ExpectationMet(ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation), outcome.expected, items);
47
+ }
48
+ );
25
49
  }
26
50
  }
@@ -7,12 +7,13 @@ export * from './equals';
7
7
  export * from './includes';
8
8
  export * from './isAfter';
9
9
  export * from './isBefore';
10
+ export * from './isCloseTo';
10
11
  export * from './isFalse';
11
12
  export * from './isGreaterThan';
12
13
  export * from './isLessThan';
14
+ export * from './isPresent';
13
15
  export * from './isTrue';
14
16
  export * from './matches';
15
17
  export * from './not';
16
18
  export * from './or';
17
- export * from './property';
18
19
  export * from './startsWith';
@@ -0,0 +1,60 @@
1
+ import { Answerable, AnswersQuestions, d, Expectation, ExpectationMet, ExpectationNotMet } from '@serenity-js/core';
2
+
3
+ /**
4
+ * @desc
5
+ * Expectation that the actual value is within a given ± absolute tolerance range of the expected value.
6
+ *
7
+ * @example
8
+ * import { actorCalled } from '@serenity-js/core'
9
+ * import { Ensure, isCloseTo } from '@serenity-js/assertions'
10
+ *
11
+ * await actorCalled('Iris').attemptsTo(
12
+ * Ensure.that(10.123, isCloseTo(10, 0.2))
13
+ * )
14
+ *
15
+ * @param {Answerable<number>} expected
16
+ * @param {Answerable<number>} [absoluteTolerance=1e-9]
17
+ */
18
+ export function isCloseTo(expected: Answerable<number>, absoluteTolerance: Answerable<number> = 1e-9): Expectation<number> {
19
+ return new IsCloseTo(expected, absoluteTolerance);
20
+ }
21
+
22
+ /**
23
+ * @package
24
+ */
25
+ class IsCloseTo extends Expectation<number> {
26
+
27
+ constructor(
28
+ private readonly expected: Answerable<number>,
29
+ private readonly absoluteTolerance: Answerable<number>,
30
+ ) {
31
+ super(
32
+ d`have value close to ${ expected } ±${ absoluteTolerance }`,
33
+ async (actor: AnswersQuestions, actual: Answerable<number>) => {
34
+
35
+ const actualValue: number = await actor.answer(actual);
36
+ const expectedValue: number = await actor.answer(this.expected);
37
+ const tolerance: number = await actor.answer(this.absoluteTolerance);
38
+
39
+ const description = `have value close to ${ expectedValue } ±${ tolerance }`
40
+
41
+ // short-circuit exact equality
42
+ if (actualValue === expectedValue) {
43
+ return new ExpectationMet(description, expectedValue, actualValue);
44
+ }
45
+
46
+ if (! (Number.isFinite(actualValue) && Number.isFinite(expectedValue))) {
47
+ return new ExpectationNotMet(description, expectedValue, actualValue);
48
+ }
49
+
50
+ const difference = Math.abs(actualValue - expectedValue)
51
+
52
+ const isClose = difference <= tolerance;
53
+
54
+ return isClose
55
+ ? new ExpectationMet(description, expectedValue, actualValue)
56
+ : new ExpectationNotMet(description, expectedValue, actualValue);
57
+ }
58
+ );
59
+ }
60
+ }
@@ -3,5 +3,5 @@ import { Expectation } from '@serenity-js/core';
3
3
  import { equals } from './equals';
4
4
 
5
5
  export function isFalse(): Expectation<boolean> {
6
- return Expectation.to<boolean>(`equal false`).soThatActual(equals(false));
6
+ return Expectation.to<never, boolean>(`equal false`).soThatActual(equals(false));
7
7
  }
@@ -0,0 +1,58 @@
1
+ import { Answerable, AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, Optional } from '@serenity-js/core';
2
+
3
+ /**
4
+ * @desc
5
+ * Expectation that the `actual` is not undefined or null.
6
+ * Also, for `actual` implementing {@link @serenity-js/core/lib/screenplay~Optional}, that `Optional.isPresent()` returns an {@link @serenity-js/core/lib/screenplay~Answerable}
7
+ * that resolves to `true`
8
+ *
9
+ * @returns {@serenity-js/core/lib/screenplay/questions~Expectation<Answerable<boolean>, Optional>}
10
+ *
11
+ * @see {@link @serenity-js/assertions~Ensure}
12
+ * @see {@link @serenity-js/core/lib/screenplay/questions~Check}
13
+ * @see {@link @serenity-js/core/lib/screenplay/interactions~Wait}
14
+ */
15
+ export function isPresent<Actual>(): Expectation<Actual> {
16
+ return new IsPresent<Actual>();
17
+ }
18
+
19
+ class IsPresent<Actual> extends Expectation<Actual> {
20
+ private static isOptional(value: any): value is Optional {
21
+ return value !== undefined
22
+ && value !== null
23
+ && typeof value.isPresent === 'function';
24
+ }
25
+
26
+ private static valueToCheck<A>(actual: Answerable<A>, actor: AnswersQuestions): Answerable<A> {
27
+ if (IsPresent.isOptional(actual)) {
28
+ return actual;
29
+ }
30
+
31
+ return actor.answer(actual);
32
+ }
33
+
34
+ private static async isPresent<A>(value: Answerable<A>, actor: AnswersQuestions): Promise<boolean> {
35
+ if (IsPresent.isOptional(value)) {
36
+ return actor.answer(value.isPresent());
37
+ }
38
+
39
+ return value !== undefined
40
+ && value !== null;
41
+ }
42
+
43
+ constructor() {
44
+ super(
45
+ 'become present',
46
+ async (actor: AnswersQuestions, actual: Answerable<Actual>) => {
47
+
48
+ const value = await IsPresent.valueToCheck(actual, actor);
49
+
50
+ const result = await IsPresent.isPresent(value, actor);
51
+
52
+ return result
53
+ ? new ExpectationMet('become present', undefined, undefined)
54
+ : new ExpectationNotMet('become present', undefined, undefined);
55
+ }
56
+ );
57
+ }
58
+ }
@@ -3,5 +3,5 @@ import { Expectation } from '@serenity-js/core';
3
3
  import { equals } from './equals';
4
4
 
5
5
  export function isTrue(): Expectation<boolean> {
6
- return Expectation.to<boolean>(`equal true`).soThatActual(equals(true));
6
+ return Expectation.to<never, boolean>(`equal true`).soThatActual(equals(true));
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { Answerable, Expectation } from '@serenity-js/core';
2
2
 
3
- export function matches(expected: Answerable<RegExp>): Expectation<RegExp, string> {
3
+ export function matches(expected: Answerable<RegExp>): Expectation<string> {
4
4
  return Expectation.thatActualShould<RegExp, string>('match', expected)
5
5
  .soThat((actualValue, expectedValue) => expectedValue.test(actualValue));
6
6
  }
@@ -1,31 +1,31 @@
1
- import { AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
2
- import { match } from 'tiny-types';
1
+ import { Answerable, AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet } from '@serenity-js/core';
3
2
 
4
- export function not<Expected, Actual>(assertion: Expectation<Expected, Actual>): Expectation<Expected, Actual> {
5
- return new Not<Expected, Actual>(assertion);
3
+ export function not<Actual>(assertion: Expectation<Actual>): Expectation<Actual> {
4
+ return new Not<Actual>(assertion);
6
5
  }
7
6
 
8
7
  /**
9
8
  * @package
10
9
  */
11
- class Not<Expected, Actual> extends Expectation<Expected, Actual> {
10
+ class Not<Actual> extends Expectation<Actual> {
12
11
  private static flipped(message: string): string {
13
12
  return message.startsWith('not ')
14
13
  ? message.slice(4)
15
14
  : `not ${ message }`;
16
15
  }
17
16
 
18
- constructor(private readonly expectation: Expectation<Expected, Actual>) {
19
- super(Not.flipped(expectation.toString()));
20
- }
17
+ constructor(private readonly expectation: Expectation<Actual>) {
18
+ super(
19
+ Not.flipped(expectation.toString()),
20
+ async (actor: AnswersQuestions, actual: Answerable<Actual>) => {
21
+ const subject = Not.flipped(expectation.toString());
21
22
 
22
- answeredBy(actor: AnswersQuestions): (actual: Actual) => Promise<ExpectationOutcome<Expected, Actual>> {
23
+ const outcome = await actor.answer(expectation.isMetFor(actual));
23
24
 
24
- return (actual: any) =>
25
- this.expectation.answeredBy(actor)(actual)
26
- .then((outcome: ExpectationOutcome<Expected, Actual>) =>
27
- match<ExpectationOutcome<Expected, Actual>, ExpectationOutcome<Expected, Actual>>(outcome)
28
- .when(ExpectationMet, o => new ExpectationNotMet(this.subject, o.expected, o.actual))
29
- .else(o => new ExpectationMet(this.subject, o.expected, o.actual)));
25
+ return outcome instanceof ExpectationNotMet
26
+ ? new ExpectationMet(subject, outcome.expected, outcome.actual)
27
+ : new ExpectationNotMet(subject, outcome.expected, outcome.actual);
28
+ }
29
+ );
30
30
  }
31
31
  }
@@ -1,41 +1,44 @@
1
- import { AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
1
+ import { Answerable, AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome, LogicError } from '@serenity-js/core';
2
2
 
3
- export function or<Actual>(...assertions: Array<Expectation<any, Actual>>): Expectation<any, Actual> {
3
+ export function or<Actual>(...assertions: Array<Expectation<Actual>>): Expectation<Actual> {
4
4
  return new Or(assertions);
5
5
  }
6
6
 
7
7
  /**
8
8
  * @package
9
9
  */
10
- class Or<Actual> extends Expectation<any, Actual> {
10
+ class Or<Actual> extends Expectation<Actual> {
11
11
  private static readonly Separator = ' or ';
12
12
 
13
- constructor(private readonly expectations: Array<Expectation<any, Actual>>) {
14
- super(expectations
15
- .map(assertion => assertion.toString())
16
- .join(Or.Separator));
13
+ private static descriptionFor<A>(expectations: Array<Expectation<A>>): string {
14
+ return expectations
15
+ .map(expectation => expectation.toString())
16
+ .join(Or.Separator);
17
17
  }
18
18
 
19
- answeredBy(actor: AnswersQuestions): (actual: Actual) => Promise<ExpectationOutcome<any, Actual>> {
19
+ constructor(private readonly expectations: Array<Expectation<Actual>>) {
20
+ super(
21
+ Or.descriptionFor(expectations),
22
+ async (actor: AnswersQuestions, actual: Answerable<Actual>) => {
23
+ if (! expectations || expectations.length === 0) {
24
+ throw new LogicError(`No expectations provided to or()`);
25
+ }
20
26
 
21
- return (actual: any) =>
22
- this.expectations.reduce(
23
- (previous, current) =>
24
- previous.then((outcomesSoFar: Array<ExpectationOutcome<any, Actual>>) =>
25
- current.answeredBy(actor)(actual)
26
- .then(outcome => outcomesSoFar.concat(outcome)), // todo: should stop on the first met expectation
27
- ),
28
- Promise.resolve([]),
29
- ).
30
- then((outcomes: Array<ExpectationOutcome<any, Actual>>) => {
27
+ let outcome: ExpectationOutcome<unknown, Actual>;
28
+ for (const expectation of expectations) {
29
+ outcome = await actor.answer(expectation.isMetFor(actual));
31
30
 
32
- const
33
- unmetExpectations = outcomes.filter(outcome => outcome instanceof ExpectationNotMet),
34
- message = outcomes.map(outcome => outcome.message).join(Or.Separator);
31
+ if (outcome instanceof ExpectationMet) {
32
+ return outcome;
33
+ }
34
+ }
35
35
 
36
- return unmetExpectations.length === this.expectations.length
37
- ? new ExpectationNotMet(message, outcomes[0].expected, outcomes[0].actual)
38
- : new ExpectationMet(message, outcomes[0].expected, outcomes[0].actual);
39
- });
36
+ return new ExpectationNotMet(
37
+ Or.descriptionFor(expectations),
38
+ outcome.expected,
39
+ outcome.actual,
40
+ );
41
+ }
42
+ );
40
43
  }
41
44
  }
@@ -1,2 +0,0 @@
1
- import { Expectation } from '@serenity-js/core';
2
- export declare function property<Actual, Property extends keyof Actual>(propertyName: Property, expectation: Expectation<any, Actual[Property]>): Expectation<Actual[Property], Actual>;
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.property = void 0;
4
- const core_1 = require("@serenity-js/core");
5
- const io_1 = require("@serenity-js/core/lib/io");
6
- function property(propertyName, expectation) {
7
- return new HasProperty(propertyName, expectation);
8
- }
9
- exports.property = property;
10
- /**
11
- * @package
12
- */
13
- class HasProperty extends core_1.Expectation {
14
- constructor(propertyName, expectation) {
15
- super((0, io_1.formatted) `have property ${propertyName} that does ${expectation}`);
16
- this.propertyName = propertyName;
17
- this.expectation = expectation;
18
- }
19
- answeredBy(actor) {
20
- return (actual) => this.expectation.answeredBy(actor)(actual[this.propertyName])
21
- .then((outcome) => {
22
- return outcome instanceof core_1.ExpectationMet
23
- ? new core_1.ExpectationMet(this.toString(), outcome.expected, actual[this.propertyName])
24
- : new core_1.ExpectationNotMet(this.toString(), outcome.expected, actual[this.propertyName]);
25
- });
26
- }
27
- }
28
- //# sourceMappingURL=property.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"property.js","sourceRoot":"","sources":["../../src/expectations/property.ts"],"names":[],"mappings":";;;AAAA,4CAAyH;AACzH,iDAAqD;AAErD,SAAgB,QAAQ,CACpB,YAAsB,EACtB,WAA+C;IAE/C,OAAO,IAAI,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AALD,4BAKC;AAED;;GAEG;AACH,MAAM,WAAmD,SAAQ,kBAAqC;IAClG,YACqB,YAAsB,EACtB,WAA+C;QAEhE,KAAK,CAAC,IAAA,cAAS,EAAC,iBAAkB,YAAa,cAAe,WAAY,EAAE,CAAC,CAAC;QAH7D,iBAAY,GAAZ,YAAY,CAAU;QACtB,gBAAW,GAAX,WAAW,CAAoC;IAGpE,CAAC;IAED,UAAU,CAAC,KAAuB;QAE9B,OAAO,CAAC,MAAc,EAAE,EAAE,CACtB,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;aACxD,IAAI,CAAC,CAAC,OAAkD,EAAE,EAAE;YAEzD,OAAO,OAAO,YAAY,qBAAc;gBACpC,CAAC,CAAC,IAAI,qBAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAClF,CAAC,CAAC,IAAI,wBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9F,CAAC,CAAC,CAAC;IACf,CAAC;CACJ"}
@@ -1,33 +0,0 @@
1
- import { AnswersQuestions, Expectation, ExpectationMet, ExpectationNotMet, ExpectationOutcome } from '@serenity-js/core';
2
- import { formatted } from '@serenity-js/core/lib/io';
3
-
4
- export function property<Actual, Property extends keyof Actual>(
5
- propertyName: Property,
6
- expectation: Expectation<any, Actual[Property]>,
7
- ): Expectation<Actual[Property], Actual> {
8
- return new HasProperty(propertyName, expectation);
9
- }
10
-
11
- /**
12
- * @package
13
- */
14
- class HasProperty<Property extends keyof Actual, Actual> extends Expectation<Actual[Property], Actual> {
15
- constructor(
16
- private readonly propertyName: Property,
17
- private readonly expectation: Expectation<any, Actual[Property]>,
18
- ) {
19
- super(formatted `have property ${ propertyName } that does ${ expectation }`);
20
- }
21
-
22
- answeredBy(actor: AnswersQuestions): (actual: Actual) => Promise<ExpectationOutcome<Actual[Property], any>> {
23
-
24
- return (actual: Actual) =>
25
- this.expectation.answeredBy(actor)(actual[this.propertyName])
26
- .then((outcome: ExpectationOutcome<any, Actual[Property]>) => {
27
-
28
- return outcome instanceof ExpectationMet
29
- ? new ExpectationMet(this.toString(), outcome.expected, actual[this.propertyName])
30
- : new ExpectationNotMet(this.toString(), outcome.expected, actual[this.propertyName]);
31
- });
32
- }
33
- }