@serenity-js/assertions 3.0.0-rc.3 → 3.0.0-rc.7

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 (46) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/lib/Ensure.d.ts +1 -1
  3. package/lib/Ensure.js +7 -10
  4. package/lib/Ensure.js.map +1 -1
  5. package/lib/expectations/and.d.ts +1 -1
  6. package/lib/expectations/and.js +6 -6
  7. package/lib/expectations/and.js.map +1 -1
  8. package/lib/expectations/contain.d.ts +1 -1
  9. package/lib/expectations/containAtLeastOneItemThat.d.ts +1 -1
  10. package/lib/expectations/containAtLeastOneItemThat.js +16 -9
  11. package/lib/expectations/containAtLeastOneItemThat.js.map +1 -1
  12. package/lib/expectations/containItemsWhereEachItem.d.ts +1 -1
  13. package/lib/expectations/containItemsWhereEachItem.js +16 -9
  14. package/lib/expectations/containItemsWhereEachItem.js.map +1 -1
  15. package/lib/expectations/index.d.ts +1 -1
  16. package/lib/expectations/index.js +1 -1
  17. package/lib/expectations/index.js.map +1 -1
  18. package/lib/expectations/isFalse.js.map +1 -1
  19. package/lib/expectations/isPresent.d.ts +14 -0
  20. package/lib/expectations/isPresent.js +50 -0
  21. package/lib/expectations/isPresent.js.map +1 -0
  22. package/lib/expectations/isTrue.js.map +1 -1
  23. package/lib/expectations/matches.d.ts +1 -1
  24. package/lib/expectations/not.d.ts +1 -1
  25. package/lib/expectations/not.js +7 -8
  26. package/lib/expectations/not.js.map +1 -1
  27. package/lib/expectations/or.d.ts +1 -1
  28. package/lib/expectations/or.js +17 -12
  29. package/lib/expectations/or.js.map +1 -1
  30. package/package.json +4 -4
  31. package/src/Ensure.ts +17 -21
  32. package/src/expectations/and.ts +19 -18
  33. package/src/expectations/contain.ts +1 -1
  34. package/src/expectations/containAtLeastOneItemThat.ts +38 -14
  35. package/src/expectations/containItemsWhereEachItem.ts +38 -14
  36. package/src/expectations/index.ts +1 -1
  37. package/src/expectations/isFalse.ts +1 -1
  38. package/src/expectations/isPresent.ts +58 -0
  39. package/src/expectations/isTrue.ts +1 -1
  40. package/src/expectations/matches.ts +1 -1
  41. package/src/expectations/not.ts +15 -15
  42. package/src/expectations/or.ts +28 -25
  43. package/lib/expectations/property.d.ts +0 -2
  44. package/lib/expectations/property.js +0 -28
  45. package/lib/expectations/property.js.map +0 -1
  46. package/src/expectations/property.ts +0 -33
package/CHANGELOG.md CHANGED
@@ -3,6 +3,81 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.0.0-rc.7](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.6...v3.0.0-rc.7) (2022-01-28)
7
+
8
+
9
+ ### Features
10
+
11
+ * **assertions:** isPresent works with any Optional ([cea75dc](https://github.com/serenity-js/serenity-js/commit/cea75dc1c728e45e06a87aaf9c1573a237334285)), closes [#1103](https://github.com/serenity-js/serenity-js/issues/1103)
12
+ * **core:** replaced `Adapter` with `QuestionAdapter` and introduced `Optional` ([8d84ad3](https://github.com/serenity-js/serenity-js/commit/8d84ad3863e3c726533d0f21934fb1e2fa8b3022)), closes [#1103](https://github.com/serenity-js/serenity-js/issues/1103)
13
+ * **core:** support for Optional chaining, expectation isPresent, refactored Expectations ([1841ee5](https://github.com/serenity-js/serenity-js/commit/1841ee5fc48cfa403ddc53358f75764d9a010c21)), closes [#1099](https://github.com/serenity-js/serenity-js/issues/1099) [#1099](https://github.com/serenity-js/serenity-js/issues/1099) [#1103](https://github.com/serenity-js/serenity-js/issues/1103)
14
+
15
+
16
+
17
+
18
+
19
+ # [3.0.0-rc.6](https://github.com/serenity-js/serenity-js/compare/v2.32.7...v3.0.0-rc.6) (2022-01-10)
20
+
21
+
22
+
23
+ # [3.0.0-rc.5](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.4...v3.0.0-rc.5) (2022-01-07)
24
+
25
+
26
+
27
+ # [3.0.0-rc.4](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.3...v3.0.0-rc.4) (2021-12-30)
28
+
29
+
30
+
31
+ # [3.0.0-rc.3](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.2...v3.0.0-rc.3) (2021-12-29)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * **deps:** updated tiny-types to 1.17.0 ([3187051](https://github.com/serenity-js/serenity-js/commit/3187051594158b4b450c82e851e417fd2ed21652))
37
+
38
+
39
+
40
+ # [3.0.0-rc.2](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.1...v3.0.0-rc.2) (2021-12-09)
41
+
42
+
43
+
44
+ # [3.0.0-rc.1](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.0...v3.0.0-rc.1) (2021-12-09)
45
+
46
+
47
+
48
+ # [3.0.0-rc.0](https://github.com/serenity-js/serenity-js/compare/v2.32.5...v3.0.0-rc.0) (2021-12-08)
49
+
50
+
51
+ ### Bug Fixes
52
+
53
+ * **core:** 3.0 RC ([469d54e](https://github.com/serenity-js/serenity-js/commit/469d54e4f81ef430566b93852e3174826f8ef672)), closes [#805](https://github.com/serenity-js/serenity-js/issues/805)
54
+
55
+
56
+ ### BREAKING CHANGES
57
+
58
+ * **core:** Introduced @serenity-js/web - a shared library for Serenity/JS Web integration
59
+ modules such as @serenity-js/protractor and @serenity-js/webdriverio. Dropped support for Node 12.
60
+
61
+
62
+
63
+
64
+
65
+ # [3.0.0-rc.5](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.4...v3.0.0-rc.5) (2022-01-07)
66
+
67
+ **Note:** Version bump only for package @serenity-js/assertions
68
+
69
+
70
+
71
+
72
+
73
+ # [3.0.0-rc.4](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.3...v3.0.0-rc.4) (2021-12-30)
74
+
75
+ **Note:** Version bump only for package @serenity-js/assertions
76
+
77
+
78
+
79
+
80
+
6
81
  # [3.0.0-rc.3](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.2...v3.0.0-rc.3) (2021-12-29)
7
82
 
8
83
 
@@ -44,9 +119,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
44
119
  modules such as @serenity-js/protractor and @serenity-js/webdriverio. Dropped support for Node 12.
45
120
 
46
121
 
122
+ ## [2.32.7](https://github.com/serenity-js/serenity-js/compare/v2.32.6...v2.32.7) (2022-01-10)
123
+
124
+ **Note:** Version bump only for package @serenity-js/assertions
125
+
126
+
47
127
 
48
128
 
49
129
 
130
+ ## [2.32.6](https://github.com/serenity-js/serenity-js/compare/v2.32.5...v2.32.6) (2022-01-10)
131
+
132
+ **Note:** Version bump only for package @serenity-js/assertions
133
+
134
+
50
135
  ## [2.32.5](https://github.com/serenity-js/serenity-js/compare/v2.32.4...v2.32.5) (2021-12-08)
51
136
 
52
137
  **Note:** Version bump only for package @serenity-js/assertions
package/lib/Ensure.d.ts CHANGED
@@ -52,7 +52,7 @@ export declare class Ensure<Actual> extends Interaction {
52
52
  *
53
53
  * @returns {Ensure<A>}
54
54
  */
55
- static that<A>(actual: Answerable<A>, expectation: Expectation<any, A>): Ensure<A>;
55
+ static that<A>(actual: Answerable<A>, expectation: Expectation<A>): Ensure<A>;
56
56
  /**
57
57
  * @param {@serenity-js/core/lib/screenplay~Answerable<T>} actual
58
58
  * @param {@serenity-js/core/lib/screenplay/questions~Expectation<T>} expectation
package/lib/Ensure.js CHANGED
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Ensure = void 0;
4
4
  const core_1 = require("@serenity-js/core");
5
- const io_1 = require("@serenity-js/core/lib/io");
6
5
  const inspected_1 = require("@serenity-js/core/lib/io/inspected");
7
6
  const model_1 = require("@serenity-js/core/lib/model");
8
7
  const tiny_types_1 = require("tiny-types");
@@ -82,19 +81,17 @@ class Ensure extends core_1.Interaction {
82
81
  * @see {@link @serenity-js/core/lib/screenplay/actor~CollectsArtifacts}
83
82
  * @see {@link @serenity-js/core/lib/screenplay/actor~AnswersQuestions}
84
83
  */
85
- performAs(actor) {
86
- return Promise.all([
87
- actor.answer(this.actual),
88
- actor.answer(this.expectation),
89
- ]).then(([actual, expectation]) => expectation(actual).then(outcome => (0, tiny_types_1.match)(outcome)
84
+ async performAs(actor) {
85
+ const outcome = await actor.answer(this.expectation.isMetFor(this.actual));
86
+ return (0, tiny_types_1.match)(outcome)
90
87
  .when(core_1.ExpectationNotMet, o => {
91
88
  actor.collect(this.artifactFrom(o.expected, o.actual), new model_1.Name(`Assertion Report`));
92
89
  throw this.errorForOutcome(o);
93
90
  })
94
91
  .when(core_1.ExpectationMet, _ => void 0)
95
92
  .else(o => {
96
- throw new core_1.LogicError((0, io_1.formatted) `An Expectation should return an instance of an ExpectationOutcome, not ${o}`);
97
- })));
93
+ throw new core_1.LogicError((0, core_1.f) `Expectation#isMetFor(actual) should return an instance of an ExpectationOutcome, not ${o}`);
94
+ });
98
95
  }
99
96
  /**
100
97
  * @desc
@@ -103,7 +100,7 @@ class Ensure extends core_1.Interaction {
103
100
  * @returns {string}
104
101
  */
105
102
  toString() {
106
- return (0, io_1.formatted) `#actor ensures that ${this.actual} does ${this.expectation}`;
103
+ return (0, core_1.d) `#actor ensures that ${this.actual} does ${this.expectation}`;
107
104
  }
108
105
  /**
109
106
  * @desc
@@ -143,7 +140,7 @@ class Ensure extends core_1.Interaction {
143
140
  * @protected
144
141
  */
145
142
  asAssertionError(outcome) {
146
- return new core_1.AssertionError(`Expected ${(0, io_1.formatted) `${this.actual}`} to ${outcome.message}`, outcome.expected, outcome.actual);
143
+ return new core_1.AssertionError(`Expected ${(0, core_1.d) `${this.actual}`} to ${outcome.message}`, outcome.expected, outcome.actual);
147
144
  }
148
145
  artifactFrom(expected, actual) {
149
146
  return model_1.AssertionReport.fromJSON({
package/lib/Ensure.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Ensure.js","sourceRoot":"","sources":["../src/Ensure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Ensure.js","sourceRoot":"","sources":["../src/Ensure.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  import { Expectation } from '@serenity-js/core';
2
- export declare function and<Actual>(...expectations: Array<Expectation<any, Actual>>): Expectation<any, Actual>;
2
+ export declare function and<Actual>(...expectations: Array<Expectation<Actual>>): Expectation<Actual>;
@@ -12,13 +12,13 @@ exports.and = and;
12
12
  */
13
13
  class And extends core_1.Expectation {
14
14
  constructor(expectations) {
15
- super(expectations.map(assertion => assertion.toString()).join(' and '));
15
+ super(expectations.map(expectation => expectation.toString()).join(And.Separator), (actor, actual) => {
16
+ return expectations.reduce((previous, current) => previous.then(outcome => (0, tiny_types_1.match)(outcome)
17
+ .when(core_1.ExpectationNotMet, o => o)
18
+ .else(_ => actor.answer(current.isMetFor(actual)))), Promise.resolve(void 0));
19
+ });
16
20
  this.expectations = expectations;
17
21
  }
18
- answeredBy(actor) {
19
- return (actual) => this.expectations.reduce((previous, current) => previous.then(outcome => (0, tiny_types_1.match)(outcome)
20
- .when(core_1.ExpectationNotMet, o => o)
21
- .else(_ => current.answeredBy(actor)(actual))), Promise.resolve(void 0));
22
- }
23
22
  }
23
+ And.Separator = ' and ';
24
24
  //# sourceMappingURL=and.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"and.js","sourceRoot":"","sources":["../../src/expectations/and.ts"],"names":[],"mappings":";;;AAAA,4CAAyG;AACzG,2CAAmC;AAEnC,SAAgB,GAAG,CAAS,GAAG,YAA6C;IACxE,OAAO,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;AACjC,CAAC;AAFD,kBAEC;AAED;;GAEG;AACH,MAAM,GAAY,SAAQ,kBAAwB;IAC9C,YAA6B,YAA6C;QACtE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QADhD,iBAAY,GAAZ,YAAY,CAAiC;IAE1E,CAAC;IAED,UAAU,CAAC,KAAuB;QAE9B,OAAO,CAAC,MAAW,EAAE,EAAE,CACnB,IAAI,CAAC,YAAY,CAAC,MAAM,CACpB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAClB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACpB,IAAA,kBAAK,EAAC,OAAO,CAAC;aACT,IAAI,CAAC,wBAAiB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;aAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CACpD,EACL,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC1B,CAAC;IACV,CAAC;CACJ"}
1
+ {"version":3,"file":"and.js","sourceRoot":"","sources":["../../src/expectations/and.ts"],"names":[],"mappings":";;;AAAA,4CAAiG;AACjG,2CAAmC;AAEnC,SAAgB,GAAG,CAAS,GAAG,YAAwC;IACnE,OAAO,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;AACjC,CAAC;AAFD,kBAEC;AAED;;GAEG;AACH,MAAM,GAAY,SAAQ,kBAAmB;IAGzC,YAA6B,YAAwC;QACjE,KAAK,CACD,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAC3E,CAAC,KAAuB,EAAE,MAA0B,EAAE,EAAE;YACpD,OAAO,YAAY,CAAC,MAAM,CACtB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAClB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACpB,IAAA,kBAAK,EAAC,OAAO,CAAC;iBACT,IAAI,CAAC,wBAAiB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CACzD,EACL,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAC1B,CAAC;QACN,CAAC,CACJ,CAAC;QAduB,iBAAY,GAAZ,YAAY,CAA4B;IAerE,CAAC;;AAjBuB,aAAS,GAAG,OAAO,CAAC"}
@@ -1,2 +1,2 @@
1
1
  import { Answerable, Expectation } from '@serenity-js/core';
2
- export declare function contain<Item>(expected: Answerable<Item>): Expectation<Item, Item[]>;
2
+ export declare function contain<Item>(expected: Answerable<Item>): Expectation<Item[]>;
@@ -1,2 +1,2 @@
1
1
  import { Expectation } from '@serenity-js/core';
2
- export declare function containAtLeastOneItemThat<Actual>(expectation: Expectation<any, Actual>): Expectation<any, Actual[]>;
2
+ export declare function containAtLeastOneItemThat<Actual>(expectation: Expectation<Actual>): Expectation<Actual[]>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.containAtLeastOneItemThat = void 0;
4
4
  const core_1 = require("@serenity-js/core");
5
- const io_1 = require("@serenity-js/core/lib/io");
6
5
  function containAtLeastOneItemThat(expectation) {
7
6
  return new ContainAtLeastOneItemThatMeetsExpectation(expectation);
8
7
  }
@@ -12,16 +11,24 @@ exports.containAtLeastOneItemThat = containAtLeastOneItemThat;
12
11
  */
13
12
  class ContainAtLeastOneItemThatMeetsExpectation extends core_1.Expectation {
14
13
  constructor(expectation) {
15
- super((0, io_1.formatted) `contain at least one item that does ${expectation}`);
14
+ super(ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation), async (actor, actual) => {
15
+ const items = await actor.answer(actual);
16
+ if (!items || items.length === 0) {
17
+ return new core_1.ExpectationNotMet(ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation), undefined, items);
18
+ }
19
+ let outcome;
20
+ for (const item of items) {
21
+ outcome = await actor.answer(expectation.isMetFor(item));
22
+ if (outcome instanceof core_1.ExpectationMet) {
23
+ return new core_1.ExpectationMet(ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation), outcome.expected, items);
24
+ }
25
+ }
26
+ return new core_1.ExpectationNotMet(ContainAtLeastOneItemThatMeetsExpectation.descriptionFor(expectation), outcome.expected, items);
27
+ });
16
28
  this.expectation = expectation;
17
29
  }
18
- answeredBy(actor) {
19
- return (actual) => actual.length === 0
20
- ? Promise.resolve(new core_1.ExpectationNotMet(this.toString(), undefined, actual))
21
- : Promise.all(actual.map(item => this.expectation.answeredBy(actor)(item)))
22
- .then(results => results.some(result => result instanceof core_1.ExpectationMet)
23
- ? new core_1.ExpectationMet(this.toString(), results[0].expected, actual)
24
- : new core_1.ExpectationNotMet(this.toString(), results[0].expected, actual));
30
+ static descriptionFor(expectation) {
31
+ return (0, core_1.d) `contain at least one item that does ${expectation}`;
25
32
  }
26
33
  }
27
34
  //# sourceMappingURL=containAtLeastOneItemThat.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"containAtLeastOneItemThat.js","sourceRoot":"","sources":["../../src/expectations/containAtLeastOneItemThat.ts"],"names":[],"mappings":";;;AAAA,4CAAyH;AACzH,iDAAqD;AAErD,SAAgB,yBAAyB,CAAS,WAAqC;IACnF,OAAO,IAAI,yCAAyC,CAAC,WAAW,CAAC,CAAC;AACtE,CAAC;AAFD,8DAEC;AAED;;GAEG;AACH,MAAM,yCAA4D,SAAQ,kBAA+B;IACrG,YAA6B,WAA0C;QACnE,KAAK,CAAC,IAAA,cAAS,EAAC,uCAAwC,WAAY,EAAE,CAAC,CAAC;QAD/C,gBAAW,GAAX,WAAW,CAA+B;IAEvE,CAAC;IAED,UAAU,CAAC,KAAuB;QAC9B,OAAO,CAAC,MAAgB,EAAE,EAAE,CACxB,MAAM,CAAC,MAAM,KAAK,CAAC;YACf,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,wBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC5E,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;iBACtE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,YAAY,qBAAc,CAAC;gBACrE,CAAC,CAAC,IAAI,qBAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAClE,CAAC,CAAC,IAAI,wBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CACxE,CAAC;IAClB,CAAC;CACJ"}
1
+ {"version":3,"file":"containAtLeastOneItemThat.js","sourceRoot":"","sources":["../../src/expectations/containAtLeastOneItemThat.ts"],"names":[],"mappings":";;;AAAA,4CAAwI;AAExI,SAAgB,yBAAyB,CAAS,WAAgC;IAC9E,OAAO,IAAI,yCAAyC,CAAC,WAAW,CAAC,CAAC;AACtE,CAAC;AAFD,8DAEC;AAED;;GAEG;AACH,MAAM,yCAAkD,SAAQ,kBAAqB;IAMjF,YAA6B,WAAgC;QACzD,KAAK,CACD,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EACrE,KAAK,EAAE,KAAuB,EAAE,MAA4B,EAAE,EAAE;YAE5D,MAAM,KAAK,GAAa,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEnD,IAAI,CAAE,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC/B,OAAO,IAAI,wBAAiB,CACxB,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EACrE,SAAS,EACT,KAAK,CACR,CAAC;aACL;YAED,IAAI,OAA4C,CAAC;YAEjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBAEtB,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;gBAExD,IAAI,OAAO,YAAY,qBAAc,EAAE;oBACnC,OAAO,IAAI,qBAAc,CACrB,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EACrE,OAAO,CAAC,QAAQ,EAChB,KAAK,CACR,CAAC;iBACL;aACJ;YAED,OAAO,IAAI,wBAAiB,CAAC,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjI,CAAC,CACJ,CAAC;QAhCuB,gBAAW,GAAX,WAAW,CAAqB;IAiC7D,CAAC;IArCO,MAAM,CAAC,cAAc,CAAC,WAA6B;QACvD,OAAO,IAAA,QAAC,EAAA,uCAAwC,WAAY,EAAE,CAAC;IACnE,CAAC;CAoCJ"}
@@ -1,2 +1,2 @@
1
1
  import { Expectation } from '@serenity-js/core';
2
- export declare function containItemsWhereEachItem<Actual>(expectation: Expectation<any, Actual>): Expectation<any, Actual[]>;
2
+ export declare function containItemsWhereEachItem<Actual>(expectation: Expectation<Actual>): Expectation<Actual[]>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.containItemsWhereEachItem = void 0;
4
4
  const core_1 = require("@serenity-js/core");
5
- const io_1 = require("@serenity-js/core/lib/io");
6
5
  function containItemsWhereEachItem(expectation) {
7
6
  return new ContainItemsWhereEachItemMeetsExpectation(expectation);
8
7
  }
@@ -12,16 +11,24 @@ exports.containItemsWhereEachItem = containItemsWhereEachItem;
12
11
  */
13
12
  class ContainItemsWhereEachItemMeetsExpectation extends core_1.Expectation {
14
13
  constructor(expectation) {
15
- super((0, io_1.formatted) `contain items where each item does ${expectation}`);
14
+ super(ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation), async (actor, actual) => {
15
+ const items = await actor.answer(actual);
16
+ if (!items || items.length === 0) {
17
+ return new core_1.ExpectationNotMet(ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation), undefined, items);
18
+ }
19
+ let outcome;
20
+ for (const item of items) {
21
+ outcome = await actor.answer(expectation.isMetFor(item));
22
+ if (outcome instanceof core_1.ExpectationNotMet) {
23
+ return new core_1.ExpectationNotMet(ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation), outcome.expected, items);
24
+ }
25
+ }
26
+ return new core_1.ExpectationMet(ContainItemsWhereEachItemMeetsExpectation.descriptionFor(expectation), outcome.expected, items);
27
+ });
16
28
  this.expectation = expectation;
17
29
  }
18
- answeredBy(actor) {
19
- return (actual) => actual.length === 0
20
- ? Promise.resolve(new core_1.ExpectationNotMet(this.toString(), undefined, actual))
21
- : Promise.all(actual.map(item => this.expectation.answeredBy(actor)(item)))
22
- .then(results => results.every(result => result instanceof core_1.ExpectationMet)
23
- ? new core_1.ExpectationMet(this.toString(), results[0].expected, actual)
24
- : new core_1.ExpectationNotMet(this.toString(), results[0].expected, actual));
30
+ static descriptionFor(expectation) {
31
+ return (0, core_1.d) `contain items where each item does ${expectation}`;
25
32
  }
26
33
  }
27
34
  //# sourceMappingURL=containItemsWhereEachItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"containItemsWhereEachItem.js","sourceRoot":"","sources":["../../src/expectations/containItemsWhereEachItem.ts"],"names":[],"mappings":";;;AAAA,4CAAyH;AACzH,iDAAqD;AAErD,SAAgB,yBAAyB,CAAS,WAAqC;IACnF,OAAO,IAAI,yCAAyC,CAAC,WAAW,CAAC,CAAC;AACtE,CAAC;AAFD,8DAEC;AAED;;GAEG;AACH,MAAM,yCAA4D,SAAQ,kBAA+B;IACrG,YAA6B,WAA0C;QACnE,KAAK,CAAC,IAAA,cAAS,EAAC,sCAAuC,WAAY,EAAE,CAAC,CAAC;QAD9C,gBAAW,GAAX,WAAW,CAA+B;IAEvE,CAAC;IAED,UAAU,CAAC,KAAuB;QAC9B,OAAO,CAAC,MAAgB,EAAE,EAAE,CACxB,MAAM,CAAC,MAAM,KAAK,CAAC;YACf,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,wBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC5E,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;iBACtE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,YAAY,qBAAc,CAAC;gBACtE,CAAC,CAAC,IAAI,qBAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAClE,CAAC,CAAC,IAAI,wBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CACxE,CAAC;IAClB,CAAC;CACJ"}
1
+ {"version":3,"file":"containItemsWhereEachItem.js","sourceRoot":"","sources":["../../src/expectations/containItemsWhereEachItem.ts"],"names":[],"mappings":";;;AAAA,4CAAwI;AAExI,SAAgB,yBAAyB,CAAS,WAAgC;IAC9E,OAAO,IAAI,yCAAyC,CAAC,WAAW,CAAC,CAAC;AACtE,CAAC;AAFD,8DAEC;AAED;;GAEG;AACH,MAAM,yCAAkD,SAAQ,kBAAqB;IAMjF,YAA6B,WAAgC;QACzD,KAAK,CACD,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EACrE,KAAK,EAAE,KAAuB,EAAE,MAA4B,EAAE,EAAE;YAE5D,MAAM,KAAK,GAAa,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEnD,IAAI,CAAE,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC/B,OAAO,IAAI,wBAAiB,CACxB,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EACrE,SAAS,EACT,KAAK,CACR,CAAC;aACL;YAED,IAAI,OAA4C,CAAC;YAEjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBAEtB,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;gBAExD,IAAI,OAAO,YAAY,wBAAiB,EAAE;oBACtC,OAAO,IAAI,wBAAiB,CACxB,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EACrE,OAAO,CAAC,QAAQ,EAChB,KAAK,CACR,CAAC;iBACL;aACJ;YAED,OAAO,IAAI,qBAAc,CAAC,yCAAyC,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9H,CAAC,CACJ,CAAC;QAhCuB,gBAAW,GAAX,WAAW,CAAqB;IAiC7D,CAAC;IArCO,MAAM,CAAC,cAAc,CAAC,WAA6B;QACvD,OAAO,IAAA,QAAC,EAAA,sCAAuC,WAAY,EAAE,CAAC;IAClE,CAAC;CAoCJ"}
@@ -10,9 +10,9 @@ export * from './isBefore';
10
10
  export * from './isFalse';
11
11
  export * from './isGreaterThan';
12
12
  export * from './isLessThan';
13
+ export * from './isPresent';
13
14
  export * from './isTrue';
14
15
  export * from './matches';
15
16
  export * from './not';
16
17
  export * from './or';
17
- export * from './property';
18
18
  export * from './startsWith';
@@ -22,10 +22,10 @@ __exportStar(require("./isBefore"), exports);
22
22
  __exportStar(require("./isFalse"), exports);
23
23
  __exportStar(require("./isGreaterThan"), exports);
24
24
  __exportStar(require("./isLessThan"), exports);
25
+ __exportStar(require("./isPresent"), exports);
25
26
  __exportStar(require("./isTrue"), exports);
26
27
  __exportStar(require("./matches"), exports);
27
28
  __exportStar(require("./not"), exports);
28
29
  __exportStar(require("./or"), exports);
29
- __exportStar(require("./property"), exports);
30
30
  __exportStar(require("./startsWith"), exports);
31
31
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/expectations/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wCAAsB;AACtB,4CAA0B;AAC1B,8DAA4C;AAC5C,8DAA4C;AAC5C,6CAA2B;AAC3B,2CAAyB;AACzB,6CAA2B;AAC3B,4CAA0B;AAC1B,6CAA2B;AAC3B,4CAA0B;AAC1B,kDAAgC;AAChC,+CAA6B;AAC7B,2CAAyB;AACzB,4CAA0B;AAC1B,wCAAsB;AACtB,uCAAqB;AACrB,6CAA2B;AAC3B,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/expectations/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wCAAsB;AACtB,4CAA0B;AAC1B,8DAA4C;AAC5C,8DAA4C;AAC5C,6CAA2B;AAC3B,2CAAyB;AACzB,6CAA2B;AAC3B,4CAA0B;AAC1B,6CAA2B;AAC3B,4CAA0B;AAC1B,kDAAgC;AAChC,+CAA6B;AAC7B,8CAA4B;AAC5B,2CAAyB;AACzB,4CAA0B;AAC1B,wCAAsB;AACtB,uCAAqB;AACrB,+CAA6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"isFalse.js","sourceRoot":"","sources":["../../src/expectations/isFalse.ts"],"names":[],"mappings":";;;AAAA,4CAAgD;AAEhD,qCAAkC;AAElC,SAAgB,OAAO;IACnB,OAAO,kBAAW,CAAC,EAAE,CAAU,aAAa,CAAC,CAAC,YAAY,CAAC,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC;AAFD,0BAEC"}
1
+ {"version":3,"file":"isFalse.js","sourceRoot":"","sources":["../../src/expectations/isFalse.ts"],"names":[],"mappings":";;;AAAA,4CAAgD;AAEhD,qCAAkC;AAElC,SAAgB,OAAO;IACnB,OAAO,kBAAW,CAAC,EAAE,CAAiB,aAAa,CAAC,CAAC,YAAY,CAAC,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC;AACrF,CAAC;AAFD,0BAEC"}
@@ -0,0 +1,14 @@
1
+ import { Expectation } from '@serenity-js/core';
2
+ /**
3
+ * @desc
4
+ * Expectation that the `actual` is not undefined or null.
5
+ * Also, for `actual` implementing {@link @serenity-js/core/lib/screenplay~Optional}, that `Optional.isPresent()` returns an {@link @serenity-js/core/lib/screenplay~Answerable}
6
+ * that resolves to `true`
7
+ *
8
+ * @returns {@serenity-js/core/lib/screenplay/questions~Expectation<Answerable<boolean>, Optional>}
9
+ *
10
+ * @see {@link @serenity-js/assertions~Ensure}
11
+ * @see {@link @serenity-js/core/lib/screenplay/questions~Check}
12
+ * @see {@link Wait}
13
+ */
14
+ export declare function isPresent<Actual>(): Expectation<Actual>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPresent = void 0;
4
+ const core_1 = require("@serenity-js/core");
5
+ /**
6
+ * @desc
7
+ * Expectation that the `actual` is not undefined or null.
8
+ * Also, for `actual` implementing {@link @serenity-js/core/lib/screenplay~Optional}, that `Optional.isPresent()` returns an {@link @serenity-js/core/lib/screenplay~Answerable}
9
+ * that resolves to `true`
10
+ *
11
+ * @returns {@serenity-js/core/lib/screenplay/questions~Expectation<Answerable<boolean>, Optional>}
12
+ *
13
+ * @see {@link @serenity-js/assertions~Ensure}
14
+ * @see {@link @serenity-js/core/lib/screenplay/questions~Check}
15
+ * @see {@link Wait}
16
+ */
17
+ function isPresent() {
18
+ return new IsPresent();
19
+ }
20
+ exports.isPresent = isPresent;
21
+ class IsPresent extends core_1.Expectation {
22
+ static isOptional(value) {
23
+ return value !== undefined
24
+ && value !== null
25
+ && typeof value.isPresent === 'function';
26
+ }
27
+ static valueToCheck(actual, actor) {
28
+ if (IsPresent.isOptional(actual)) {
29
+ return actual;
30
+ }
31
+ return actor.answer(actual);
32
+ }
33
+ static async isPresent(value, actor) {
34
+ if (IsPresent.isOptional(value)) {
35
+ return actor.answer(value.isPresent());
36
+ }
37
+ return value !== undefined
38
+ && value !== null;
39
+ }
40
+ constructor() {
41
+ super('become present', async (actor, actual) => {
42
+ const value = await IsPresent.valueToCheck(actual, actor);
43
+ const result = await IsPresent.isPresent(value, actor);
44
+ return result
45
+ ? new core_1.ExpectationMet('become present', undefined, undefined)
46
+ : new core_1.ExpectationNotMet('become present', undefined, undefined);
47
+ });
48
+ }
49
+ }
50
+ //# sourceMappingURL=isPresent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isPresent.js","sourceRoot":"","sources":["../../src/expectations/isPresent.ts"],"names":[],"mappings":";;;AAAA,4CAA2H;AAE3H;;;;;;;;;;;GAWG;AACH,SAAgB,SAAS;IACrB,OAAO,IAAI,SAAS,EAAU,CAAC;AACnC,CAAC;AAFD,8BAEC;AAED,MAAM,SAAkB,SAAQ,kBAAmB;IACvC,MAAM,CAAC,UAAU,CAAC,KAAU;QAChC,OAAO,KAAK,KAAK,SAAS;eACnB,KAAK,KAAK,IAAI;eACd,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC;IACjD,CAAC;IAEO,MAAM,CAAC,YAAY,CAAI,MAAqB,EAAE,KAAuB;QACzE,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;YAC9B,OAAO,MAAM,CAAC;SACjB;QAED,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAI,KAAoB,EAAE,KAAuB;QAC3E,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;YAC7B,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;SAC1C;QAED,OAAO,KAAK,KAAK,SAAS;eACnB,KAAK,KAAK,IAAI,CAAC;IAC1B,CAAC;IAED;QACI,KAAK,CACD,gBAAgB,EAChB,KAAK,EAAE,KAAuB,EAAE,MAA0B,EAAE,EAAE;YAE1D,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAE1D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAEvD,OAAO,MAAM;gBACT,CAAC,CAAC,IAAI,qBAAc,CAAC,gBAAgB,EAAE,SAAS,EAAE,SAAS,CAAC;gBAC5D,CAAC,CAAC,IAAI,wBAAiB,CAAC,gBAAgB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACxE,CAAC,CACJ,CAAC;IACN,CAAC;CACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"isTrue.js","sourceRoot":"","sources":["../../src/expectations/isTrue.ts"],"names":[],"mappings":";;;AAAA,4CAAgD;AAEhD,qCAAkC;AAElC,SAAgB,MAAM;IAClB,OAAO,kBAAW,CAAC,EAAE,CAAU,YAAY,CAAC,CAAC,YAAY,CAAC,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC;AAFD,wBAEC"}
1
+ {"version":3,"file":"isTrue.js","sourceRoot":"","sources":["../../src/expectations/isTrue.ts"],"names":[],"mappings":";;;AAAA,4CAAgD;AAEhD,qCAAkC;AAElC,SAAgB,MAAM;IAClB,OAAO,kBAAW,CAAC,EAAE,CAAiB,YAAY,CAAC,CAAC,YAAY,CAAC,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,CAAC;AACnF,CAAC;AAFD,wBAEC"}
@@ -1,2 +1,2 @@
1
1
  import { Answerable, Expectation } from '@serenity-js/core';
2
- export declare function matches(expected: Answerable<RegExp>): Expectation<RegExp, string>;
2
+ export declare function matches(expected: Answerable<RegExp>): Expectation<string>;
@@ -1,2 +1,2 @@
1
1
  import { Expectation } from '@serenity-js/core';
2
- export declare function not<Expected, Actual>(assertion: Expectation<Expected, Actual>): Expectation<Expected, Actual>;
2
+ export declare function not<Actual>(assertion: Expectation<Actual>): Expectation<Actual>;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.not = void 0;
4
4
  const core_1 = require("@serenity-js/core");
5
- const tiny_types_1 = require("tiny-types");
6
5
  function not(assertion) {
7
6
  return new Not(assertion);
8
7
  }
@@ -12,7 +11,13 @@ exports.not = not;
12
11
  */
13
12
  class Not extends core_1.Expectation {
14
13
  constructor(expectation) {
15
- super(Not.flipped(expectation.toString()));
14
+ super(Not.flipped(expectation.toString()), async (actor, actual) => {
15
+ const subject = Not.flipped(expectation.toString());
16
+ const outcome = await actor.answer(expectation.isMetFor(actual));
17
+ return outcome instanceof core_1.ExpectationNotMet
18
+ ? new core_1.ExpectationMet(subject, outcome.expected, outcome.actual)
19
+ : new core_1.ExpectationNotMet(subject, outcome.expected, outcome.actual);
20
+ });
16
21
  this.expectation = expectation;
17
22
  }
18
23
  static flipped(message) {
@@ -20,11 +25,5 @@ class Not extends core_1.Expectation {
20
25
  ? message.slice(4)
21
26
  : `not ${message}`;
22
27
  }
23
- answeredBy(actor) {
24
- return (actual) => this.expectation.answeredBy(actor)(actual)
25
- .then((outcome) => (0, tiny_types_1.match)(outcome)
26
- .when(core_1.ExpectationMet, o => new core_1.ExpectationNotMet(this.subject, o.expected, o.actual))
27
- .else(o => new core_1.ExpectationMet(this.subject, o.expected, o.actual)));
28
- }
29
28
  }
30
29
  //# sourceMappingURL=not.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"not.js","sourceRoot":"","sources":["../../src/expectations/not.ts"],"names":[],"mappings":";;;AAAA,4CAAyH;AACzH,2CAAmC;AAEnC,SAAgB,GAAG,CAAmB,SAAwC;IAC1E,OAAO,IAAI,GAAG,CAAmB,SAAS,CAAC,CAAC;AAChD,CAAC;AAFD,kBAEC;AAED;;GAEG;AACH,MAAM,GAAsB,SAAQ,kBAA6B;IAO7D,YAA6B,WAA0C;QACnE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QADlB,gBAAW,GAAX,WAAW,CAA+B;IAEvE,CAAC;IARO,MAAM,CAAC,OAAO,CAAC,OAAe;QAClC,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,OAAQ,OAAQ,EAAE,CAAC;IAC7B,CAAC;IAMD,UAAU,CAAC,KAAuB;QAE9B,OAAO,CAAC,MAAW,EAAE,EAAE,CACnB,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;aACrC,IAAI,CAAC,CAAC,OAA6C,EAAE,EAAE,CACpD,IAAA,kBAAK,EAA6E,OAAO,CAAC;aACrF,IAAI,CAAC,qBAAc,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,wBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;aACpF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,qBAAc,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;CACJ"}
1
+ {"version":3,"file":"not.js","sourceRoot":"","sources":["../../src/expectations/not.ts"],"names":[],"mappings":";;;AAAA,4CAAiH;AAEjH,SAAgB,GAAG,CAAS,SAA8B;IACtD,OAAO,IAAI,GAAG,CAAS,SAAS,CAAC,CAAC;AACtC,CAAC;AAFD,kBAEC;AAED;;GAEG;AACH,MAAM,GAAY,SAAQ,kBAAmB;IAOzC,YAA6B,WAAgC;QACzD,KAAK,CACD,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,EACnC,KAAK,EAAE,KAAuB,EAAE,MAA0B,EAAE,EAAE;YAC1D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;YAEpD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAEjE,OAAO,OAAO,YAAY,wBAAiB;gBACvC,CAAC,CAAC,IAAI,qBAAc,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC;gBAC/D,CAAC,CAAC,IAAI,wBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3E,CAAC,CACJ,CAAC;QAZuB,gBAAW,GAAX,WAAW,CAAqB;IAa7D,CAAC;IAnBO,MAAM,CAAC,OAAO,CAAC,OAAe;QAClC,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,OAAQ,OAAQ,EAAE,CAAC;IAC7B,CAAC;CAgBJ"}
@@ -1,2 +1,2 @@
1
1
  import { Expectation } from '@serenity-js/core';
2
- export declare function or<Actual>(...assertions: Array<Expectation<any, Actual>>): Expectation<any, Actual>;
2
+ export declare function or<Actual>(...assertions: Array<Expectation<Actual>>): Expectation<Actual>;
@@ -11,20 +11,25 @@ exports.or = or;
11
11
  */
12
12
  class Or extends core_1.Expectation {
13
13
  constructor(expectations) {
14
- super(expectations
15
- .map(assertion => assertion.toString())
16
- .join(Or.Separator));
14
+ super(Or.descriptionFor(expectations), async (actor, actual) => {
15
+ if (!expectations || expectations.length === 0) {
16
+ throw new core_1.LogicError(`No expectations provided to or()`);
17
+ }
18
+ let outcome;
19
+ for (const expectation of expectations) {
20
+ outcome = await actor.answer(expectation.isMetFor(actual));
21
+ if (outcome instanceof core_1.ExpectationMet) {
22
+ return outcome;
23
+ }
24
+ }
25
+ return new core_1.ExpectationNotMet(Or.descriptionFor(expectations), outcome.expected, outcome.actual);
26
+ });
17
27
  this.expectations = expectations;
18
28
  }
19
- answeredBy(actor) {
20
- return (actual) => this.expectations.reduce((previous, current) => previous.then((outcomesSoFar) => current.answeredBy(actor)(actual)
21
- .then(outcome => outcomesSoFar.concat(outcome))), Promise.resolve([])).
22
- then((outcomes) => {
23
- const unmetExpectations = outcomes.filter(outcome => outcome instanceof core_1.ExpectationNotMet), message = outcomes.map(outcome => outcome.message).join(Or.Separator);
24
- return unmetExpectations.length === this.expectations.length
25
- ? new core_1.ExpectationNotMet(message, outcomes[0].expected, outcomes[0].actual)
26
- : new core_1.ExpectationMet(message, outcomes[0].expected, outcomes[0].actual);
27
- });
29
+ static descriptionFor(expectations) {
30
+ return expectations
31
+ .map(expectation => expectation.toString())
32
+ .join(Or.Separator);
28
33
  }
29
34
  }
30
35
  Or.Separator = ' or ';
@@ -1 +1 @@
1
- {"version":3,"file":"or.js","sourceRoot":"","sources":["../../src/expectations/or.ts"],"names":[],"mappings":";;;AAAA,4CAAyH;AAEzH,SAAgB,EAAE,CAAS,GAAG,UAA2C;IACrE,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAFD,gBAEC;AAED;;GAEG;AACH,MAAM,EAAW,SAAQ,kBAAwB;IAG7C,YAA6B,YAA6C;QACtE,KAAK,CAAC,YAAY;aACb,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;aACtC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAHA,iBAAY,GAAZ,YAAY,CAAiC;IAI1E,CAAC;IAED,UAAU,CAAC,KAAuB;QAE9B,OAAO,CAAC,MAAW,EAAE,EAAE,CACnB,IAAI,CAAC,YAAY,CAAC,MAAM,CACpB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAClB,QAAQ,CAAC,IAAI,CAAC,CAAC,aAAqD,EAAE,EAAE,CACpE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;aAC5B,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CACtD,EACL,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CACtB;YACD,IAAI,CAAC,CAAC,QAAgD,EAAE,EAAE;YAEtD,MACI,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,YAAY,wBAAiB,CAAC,EACpF,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;YAE1E,OAAO,iBAAiB,CAAC,MAAM,KAAK,IAAI,CAAC,YAAY,CAAC,MAAM;gBACxD,CAAC,CAAC,IAAI,wBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC1E,CAAC,CAAC,IAAI,qBAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACX,CAAC;;AA7BuB,YAAS,GAAG,MAAM,CAAC"}
1
+ {"version":3,"file":"or.js","sourceRoot":"","sources":["../../src/expectations/or.ts"],"names":[],"mappings":";;;AAAA,4CAAiJ;AAEjJ,SAAgB,EAAE,CAAS,GAAG,UAAsC;IAChE,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC;AAFD,gBAEC;AAED;;GAEG;AACH,MAAM,EAAW,SAAQ,kBAAmB;IASxC,YAA6B,YAAwC;QACjE,KAAK,CACD,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,EAC/B,KAAK,EAAE,KAAuB,EAAE,MAA0B,EAAE,EAAE;YAC1D,IAAI,CAAE,YAAY,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC7C,MAAM,IAAI,iBAAU,CAAC,kCAAkC,CAAC,CAAC;aAC5D;YAED,IAAI,OAA4C,CAAC;YACjD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE;gBACpC,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;gBAE3D,IAAI,OAAO,YAAY,qBAAc,EAAE;oBACnC,OAAO,OAAO,CAAC;iBAClB;aACJ;YAED,OAAO,IAAI,wBAAiB,CACxB,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,EAC/B,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,MAAM,CACjB,CAAC;QACN,CAAC,CACJ,CAAC;QAvBuB,iBAAY,GAAZ,YAAY,CAA4B;IAwBrE,CAAC;IA9BO,MAAM,CAAC,cAAc,CAAI,YAAmC;QAChE,OAAO,YAAY;aACd,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;aAC1C,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;;AANuB,YAAS,GAAG,MAAM,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serenity-js/assertions",
3
- "version": "3.0.0-rc.3",
3
+ "version": "3.0.0-rc.7",
4
4
  "description": "Screenplay-style assertion library",
5
5
  "author": {
6
6
  "name": "Jan Molak",
@@ -45,7 +45,7 @@
45
45
  "npm": "^6 || ^7 || ^8"
46
46
  },
47
47
  "dependencies": {
48
- "@serenity-js/core": "3.0.0-rc.3",
48
+ "@serenity-js/core": "3.0.0-rc.7",
49
49
  "tiny-types": "^1.17.0"
50
50
  },
51
51
  "devDependencies": {
@@ -55,7 +55,7 @@
55
55
  "@types/mocha": "^9.0.0",
56
56
  "mocha": "^9.1.3",
57
57
  "ts-node": "^10.4.0",
58
- "typescript": "^4.5.2"
58
+ "typescript": "^4.5.4"
59
59
  },
60
60
  "nyc": {
61
61
  "include": [
@@ -79,5 +79,5 @@
79
79
  "cache": true,
80
80
  "all": true
81
81
  },
82
- "gitHead": "69da7444e581c457e29e87edcd910ec06a069338"
82
+ "gitHead": "74f603a7a8e0c685a0ea5e4198aad6cc30aea91c"
83
83
  }
package/src/Ensure.ts CHANGED
@@ -3,16 +3,17 @@ import {
3
3
  AnswersQuestions,
4
4
  AssertionError,
5
5
  CollectsArtifacts,
6
+ d,
6
7
  Expectation,
7
8
  ExpectationMet,
8
9
  ExpectationNotMet,
9
10
  ExpectationOutcome,
11
+ f,
10
12
  Interaction,
11
13
  LogicError,
12
14
  RuntimeError,
13
15
  UsesAbilities,
14
16
  } from '@serenity-js/core';
15
- import { formatted } from '@serenity-js/core/lib/io';
16
17
  import { inspected } from '@serenity-js/core/lib/io/inspected';
17
18
  import { Artifact, AssertionReport, Name } from '@serenity-js/core/lib/model';
18
19
  import { match } from 'tiny-types';
@@ -68,7 +69,7 @@ export class Ensure<Actual> extends Interaction {
68
69
  *
69
70
  * @returns {Ensure<A>}
70
71
  */
71
- static that<A>(actual: Answerable<A>, expectation: Expectation<any, A>): Ensure<A> {
72
+ static that<A>(actual: Answerable<A>, expectation: Expectation<A>): Ensure<A> {
72
73
  return new Ensure(actual, expectation);
73
74
  }
74
75
 
@@ -96,24 +97,19 @@ export class Ensure<Actual> extends Interaction {
96
97
  * @see {@link @serenity-js/core/lib/screenplay/actor~CollectsArtifacts}
97
98
  * @see {@link @serenity-js/core/lib/screenplay/actor~AnswersQuestions}
98
99
  */
99
- performAs(actor: UsesAbilities & AnswersQuestions & CollectsArtifacts): Promise<void> {
100
- return Promise.all([
101
- actor.answer(this.actual),
102
- actor.answer(this.expectation),
103
- ]).then(([ actual, expectation ]) =>
104
- expectation(actual).then(outcome =>
105
- match<ExpectationOutcome<unknown, Actual>, void>(outcome)
106
- .when(ExpectationNotMet, o => {
107
- actor.collect(this.artifactFrom(o.expected, o.actual), new Name(`Assertion Report`));
100
+ async performAs(actor: UsesAbilities & AnswersQuestions & CollectsArtifacts): Promise<void> {
101
+ const outcome = await actor.answer(this.expectation.isMetFor(this.actual));
108
102
 
109
- throw this.errorForOutcome(o);
110
- })
111
- .when(ExpectationMet, _ => void 0)
112
- .else(o => {
113
- throw new LogicError(formatted `An Expectation should return an instance of an ExpectationOutcome, not ${ o }`);
114
- }),
115
- ),
116
- );
103
+ return match<ExpectationOutcome<unknown, Actual>, void>(outcome)
104
+ .when(ExpectationNotMet, o => {
105
+ actor.collect(this.artifactFrom(o.expected, o.actual), new Name(`Assertion Report`));
106
+
107
+ throw this.errorForOutcome(o);
108
+ })
109
+ .when(ExpectationMet, _ => void 0)
110
+ .else(o => {
111
+ throw new LogicError(f`Expectation#isMetFor(actual) should return an instance of an ExpectationOutcome, not ${ o }`);
112
+ });
117
113
  }
118
114
 
119
115
  /**
@@ -123,7 +119,7 @@ export class Ensure<Actual> extends Interaction {
123
119
  * @returns {string}
124
120
  */
125
121
  toString(): string {
126
- return formatted `#actor ensures that ${ this.actual } does ${ this.expectation }`;
122
+ return d`#actor ensures that ${ this.actual } does ${ this.expectation }`;
127
123
  }
128
124
 
129
125
  /**
@@ -167,7 +163,7 @@ export class Ensure<Actual> extends Interaction {
167
163
  */
168
164
  protected asAssertionError(outcome: ExpectationOutcome<any, Actual>): AssertionError {
169
165
  return new AssertionError(
170
- `Expected ${ formatted`${ this.actual }` } to ${ outcome.message }`,
166
+ `Expected ${ d`${ this.actual }` } to ${ outcome.message }`,
171
167
  outcome.expected,
172
168
  outcome.actual,
173
169
  );
@@ -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
  }
@@ -10,9 +10,9 @@ export * from './isBefore';
10
10
  export * from './isFalse';
11
11
  export * from './isGreaterThan';
12
12
  export * from './isLessThan';
13
+ export * from './isPresent';
13
14
  export * from './isTrue';
14
15
  export * from './matches';
15
16
  export * from './not';
16
17
  export * from './or';
17
- export * from './property';
18
18
  export * from './startsWith';
@@ -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 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
- }