@ddd-ts-kit/testing 0.2.0 → 0.3.0
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.
- package/README.md +24 -4
- package/dist/e2e/expect-problem.d.ts +4 -1
- package/dist/e2e/expect-problem.d.ts.map +1 -1
- package/dist/e2e/expect-problem.js +10 -3
- package/dist/e2e/expect-problem.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/refusals/expect-refusal.d.ts +13 -0
- package/dist/refusals/expect-refusal.d.ts.map +1 -0
- package/dist/refusals/expect-refusal.js +64 -0
- package/dist/refusals/expect-refusal.js.map +1 -0
- package/dist/refusals/expected-facts.d.ts +3 -0
- package/dist/refusals/expected-facts.d.ts.map +1 -0
- package/dist/refusals/expected-facts.js +2 -0
- package/dist/refusals/expected-facts.js.map +1 -0
- package/dist/refusals/fact-mismatches.d.ts +4 -0
- package/dist/refusals/fact-mismatches.d.ts.map +1 -0
- package/dist/refusals/fact-mismatches.js +22 -0
- package/dist/refusals/fact-mismatches.js.map +1 -0
- package/dist/scenarios/deferred-outcome.d.ts +2 -1
- package/dist/scenarios/deferred-outcome.d.ts.map +1 -1
- package/dist/scenarios/deferred-outcome.js +2 -2
- package/dist/scenarios/deferred-outcome.js.map +1 -1
- package/dist/scenarios/immediate-outcome.d.ts +2 -1
- package/dist/scenarios/immediate-outcome.d.ts.map +1 -1
- package/dist/scenarios/immediate-outcome.js +18 -2
- package/dist/scenarios/immediate-outcome.js.map +1 -1
- package/dist/scenarios/outcome.d.ts +3 -2
- package/dist/scenarios/outcome.d.ts.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ it('records the payment of a placed order', () => {
|
|
|
161
161
|
it('refuses to pay an order twice', () => {
|
|
162
162
|
given(anOrder().paid())
|
|
163
163
|
.when((order) => order.pay())
|
|
164
|
-
.thenError(
|
|
164
|
+
.thenError('ORDER_ALREADY_PAID')
|
|
165
165
|
.thenState((order) => expect(order.status).toBe('paid'));
|
|
166
166
|
});
|
|
167
167
|
```
|
|
@@ -175,7 +175,8 @@ the same with the arrangement as a function, replayed from a fresh aggregate at
|
|
|
175
175
|
| `thenEvents([...])` | exactly these events, in order; each described by its name, its class, or the properties that matter |
|
|
176
176
|
| `thenEventNames([...])` | exactly these names, in order |
|
|
177
177
|
| `thenNoEvent()` | nothing was recorded |
|
|
178
|
-
| `thenError(
|
|
178
|
+
| `thenError(code)`, `thenError(code, facts)` | the action refused with that code, whatever the class of the error, carrying these facts when given (it may carry others) |
|
|
179
|
+
| `thenError(ErrorClass, code?)` | the action threw an instance of that class: for an error that is one class, as 0.2 wrote them |
|
|
179
180
|
| `thenState((aggregate) => ...)` | your own assertions on the aggregate pass |
|
|
180
181
|
|
|
181
182
|
Failures are `AssertionError`s of `node:assert` with the expected and recorded events side by
|
|
@@ -183,6 +184,25 @@ side, so they read well under any runner. An error raised by `when` is never swa
|
|
|
183
184
|
assertion but `thenError` fails on it. When `when` (or the arrangement) is asynchronous, the
|
|
184
185
|
chain is a promise: `await given(order).when(async (o) => ...).thenEventNames([...])`.
|
|
185
186
|
|
|
187
|
+
## Refusals
|
|
188
|
+
|
|
189
|
+
A business refusal is known by its code, and carries its facts as data: a test asserts both,
|
|
190
|
+
never a message and never the class of one refusal.
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { expectRefusal } from '@ddd-ts-kit/testing';
|
|
194
|
+
|
|
195
|
+
expectRefusal(() => calendar.slotFor('consultation', startsAt, now), 'BOOKING_TOO_LATE', { notice: 120 });
|
|
196
|
+
expectRefusal(Email.create('ada@'), 'INVALID_EMAIL');
|
|
197
|
+
await expectRefusal(() => commands.execute(command), 'SLOT_TAKEN', { calendarId: 'calendar-1' });
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`expectRefusal(subject, code, facts?)` reads an action, which it runs, a `Result`, or an error
|
|
201
|
+
already caught. An action that returns a promise gives a promise to await. It answers the
|
|
202
|
+
error, and fails with an `AssertionError` that names what was refused instead, or the facts
|
|
203
|
+
that differ, one line each. The facts given must be carried with those values; the refusal may
|
|
204
|
+
carry others.
|
|
205
|
+
|
|
186
206
|
## Handlers
|
|
187
207
|
|
|
188
208
|
```ts
|
|
@@ -292,7 +312,7 @@ afterAll(() => server.close());
|
|
|
292
312
|
| `client.get / post / put / patch / delete` | JSON in, `{ status, headers, body }` out; `body` is parsed when the content type is JSON, text otherwise; a 4xx or 5xx is a response, not an exception |
|
|
293
313
|
| `client.post(path, body, { headers })`, `client.withHeaders(headers)` | headers for one call, or a client for another caller |
|
|
294
314
|
| `expectStatus(response, 201)` | hands the response back, or fails showing the body, where the API says why |
|
|
295
|
-
| `expectProblem(response, { status, code })` | asserts an RFC 9457 `application/problem+json` answer and returns the document |
|
|
315
|
+
| `expectProblem(response, { status, code, facts })` | asserts an RFC 9457 `application/problem+json` answer and returns the document; `code` and `facts` are optional, and `facts` names the facts the document must expose, as JSON writes them (a date is its ISO text) |
|
|
296
316
|
| `eventually(assertion, { timeoutMs = 2000, intervalMs = 20 })` | retries until the assertion passes; when the time is up, fails quoting the last error |
|
|
297
317
|
| `collectEvents(subscriber, types)` | records published integration events: `received(type?)`, `waitFor(type, predicate?, options?)`, `stop()` |
|
|
298
318
|
|
|
@@ -349,7 +369,7 @@ levels of `docs/ARCHITECTURE.md` (the adapter level is the contract suites, belo
|
|
|
349
369
|
it('refuses to pay an order twice', () => {
|
|
350
370
|
given(anOrder().paid())
|
|
351
371
|
.when((order) => order.pay(at))
|
|
352
|
-
.thenError(
|
|
372
|
+
.thenError('ORDER_ALREADY_PAID');
|
|
353
373
|
});
|
|
354
374
|
|
|
355
375
|
// 2. Application: the real handler through the bus, fakes for the ports.
|
|
@@ -3,11 +3,14 @@ export interface ExpectedProblem {
|
|
|
3
3
|
readonly status: number;
|
|
4
4
|
/** The stable error code, when the answer must carry this one. */
|
|
5
5
|
readonly code?: string;
|
|
6
|
+
/** The facts the document must expose under `facts`, by name, as JSON writes them. It may expose others. */
|
|
7
|
+
readonly facts?: Readonly<Record<string, unknown>>;
|
|
6
8
|
}
|
|
7
9
|
export type ProblemDetails = Readonly<Record<string, unknown>>;
|
|
8
10
|
/**
|
|
9
11
|
* Asserts an RFC 9457 answer: the status, on the response and in the document, the
|
|
10
|
-
* `application/problem+json` content type
|
|
12
|
+
* `application/problem+json` content type, the `code` member and, when given, the exposed
|
|
13
|
+
* `facts`. Returns the document.
|
|
11
14
|
*/
|
|
12
15
|
export declare function expectProblem(response: HttpResponse, expected: ExpectedProblem): ProblemDetails;
|
|
13
16
|
//# sourceMappingURL=expect-problem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect-problem.d.ts","sourceRoot":"","sources":["../../src/e2e/expect-problem.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"expect-problem.d.ts","sourceRoot":"","sources":["../../src/e2e/expect-problem.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,4GAA4G;IAC5G,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAI/D;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,GAAG,cAAc,CAoB/F"}
|
|
@@ -2,22 +2,29 @@ import { deepStrictEqual } from 'node:assert';
|
|
|
2
2
|
const PROBLEM_JSON = 'application/problem+json';
|
|
3
3
|
/**
|
|
4
4
|
* Asserts an RFC 9457 answer: the status, on the response and in the document, the
|
|
5
|
-
* `application/problem+json` content type
|
|
5
|
+
* `application/problem+json` content type, the `code` member and, when given, the exposed
|
|
6
|
+
* `facts`. Returns the document.
|
|
6
7
|
*/
|
|
7
8
|
export function expectProblem(response, expected) {
|
|
8
9
|
const problem = isRecord(response.body) ? response.body : {};
|
|
9
10
|
const code = (value) => (expected.code === undefined ? {} : { code: value });
|
|
11
|
+
const exposed = isRecord(problem.facts) ? problem.facts : {};
|
|
12
|
+
const names = Object.keys(expected.facts ?? {});
|
|
10
13
|
deepStrictEqual({
|
|
11
14
|
status: response.status,
|
|
12
15
|
contentType: mediaTypeOf(response),
|
|
13
|
-
problem: { status: problem.status, ...code(problem.code) },
|
|
16
|
+
problem: { status: problem.status, ...code(problem.code), ...facts(names, exposed) },
|
|
14
17
|
}, {
|
|
15
18
|
status: expected.status,
|
|
16
19
|
contentType: PROBLEM_JSON,
|
|
17
|
-
problem: { status: expected.status, ...code(expected.code) },
|
|
20
|
+
problem: { status: expected.status, ...code(expected.code), ...facts(names, expected.facts ?? {}) },
|
|
18
21
|
});
|
|
19
22
|
return problem;
|
|
20
23
|
}
|
|
24
|
+
/** The named facts alone, so that the comparison shows the ones that differ and no other. */
|
|
25
|
+
function facts(names, source) {
|
|
26
|
+
return names.length === 0 ? {} : { facts: Object.fromEntries(names.map((name) => [name, source[name]])) };
|
|
27
|
+
}
|
|
21
28
|
function isRecord(value) {
|
|
22
29
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
23
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect-problem.js","sourceRoot":"","sources":["../../src/e2e/expect-problem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"expect-problem.js","sourceRoot":"","sources":["../../src/e2e/expect-problem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAa9C,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,QAAsB,EAAE,QAAyB;IAC7E,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,IAAI,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAEhD,eAAe,CACb;QACE,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,WAAW,EAAE,WAAW,CAAC,QAAQ,CAAC;QAClC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;KACrF,EACD;QACE,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,WAAW,EAAE,YAAY;QACzB,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE;KACpG,CACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6FAA6F;AAC7F,SAAS,KAAK,CAAC,KAAwB,EAAE,MAAyC;IAChF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5G,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,WAAW,CAAC,QAAsB;IACzC,OAAO,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAC/E,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export { ExecutionContextBuilder } from './execution/execution-context-builder.j
|
|
|
14
14
|
export { scoped } from './execution/scoped.js';
|
|
15
15
|
export { SessionBuilder } from './execution/session-builder.js';
|
|
16
16
|
export { createTestBuses, type TestBuses, type TestBusesOptions } from './harness/create-test-buses.js';
|
|
17
|
+
export { expectRefusal } from './refusals/expect-refusal.js';
|
|
18
|
+
export type { ExpectedFacts } from './refusals/expected-facts.js';
|
|
17
19
|
export { InMemoryRepository, type InMemoryRepositoryOptions } from './repositories/in-memory-repository.js';
|
|
18
20
|
export { snapshots } from './repositories/snapshots.js';
|
|
19
21
|
export { expectNoSecret } from './secrecy/expect-no-secret.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACxG,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,YAAY,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,YAAY,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export { ExecutionContextBuilder } from './execution/execution-context-builder.j
|
|
|
11
11
|
export { scoped } from './execution/scoped.js';
|
|
12
12
|
export { SessionBuilder } from './execution/session-builder.js';
|
|
13
13
|
export { createTestBuses } from './harness/create-test-buses.js';
|
|
14
|
+
export { expectRefusal } from './refusals/expect-refusal.js';
|
|
14
15
|
export { InMemoryRepository } from './repositories/in-memory-repository.js';
|
|
15
16
|
export { snapshots } from './repositories/snapshots.js';
|
|
16
17
|
export { expectNoSecret } from './secrecy/expect-no-secret.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAyC,MAAM,gCAAgC,CAAC;AACxG,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAK/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAiB,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAyC,MAAM,gCAAgC,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAK/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAiB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ExpectedFacts } from './expected-facts.js';
|
|
2
|
+
/**
|
|
3
|
+
* Asserts a business refusal by its code, and by its facts when given: on an error that was
|
|
4
|
+
* caught, on a `Result`, or on an action, which is run. The class of the error is not looked
|
|
5
|
+
* at. Returns the error; an action that returns a promise gives a promise to await.
|
|
6
|
+
*
|
|
7
|
+
* expectRefusal(() => appointment.cancel(at), 'APPOINTMENT_ENDED', { status: 'cancelled' });
|
|
8
|
+
* expectRefusal(Email.create('nope'), 'INVALID_EMAIL');
|
|
9
|
+
* await expectRefusal(() => bus.execute(command), 'SLOT_TAKEN');
|
|
10
|
+
*/
|
|
11
|
+
export declare function expectRefusal(subject: () => PromiseLike<unknown>, code: string, facts?: ExpectedFacts): Promise<unknown>;
|
|
12
|
+
export declare function expectRefusal(subject: unknown, code: string, facts?: ExpectedFacts): unknown;
|
|
13
|
+
//# sourceMappingURL=expect-refusal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect-refusal.d.ts","sourceRoot":"","sources":["../../src/refusals/expect-refusal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQzD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,WAAW,CAAC,OAAO,CAAC,EACnC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,OAAO,CAAC,CAAC;AACpB,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AssertionError } from 'node:assert';
|
|
2
|
+
import { isPromiseLike } from '../scenarios/is-promise-like.js';
|
|
3
|
+
import { show } from '../scenarios/show.js';
|
|
4
|
+
import { factMismatches } from './fact-mismatches.js';
|
|
5
|
+
export function expectRefusal(subject, code, facts = {}) {
|
|
6
|
+
const attempt = attempted(subject);
|
|
7
|
+
if (isPromiseLike(attempt)) {
|
|
8
|
+
return Promise.resolve(attempt).then(() => refusalOf({ refused: false }, code, facts), (error) => refusalOf({ refused: true, error }, code, facts));
|
|
9
|
+
}
|
|
10
|
+
return refusalOf(attempt, code, facts);
|
|
11
|
+
}
|
|
12
|
+
function attempted(subject) {
|
|
13
|
+
if (!isAction(subject)) {
|
|
14
|
+
return outcomeOf(subject);
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const answer = subject();
|
|
18
|
+
return isPromiseLike(answer) ? answer : outcomeOf(answer, { ran: true });
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return { refused: true, error };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function isAction(subject) {
|
|
25
|
+
return typeof subject === 'function';
|
|
26
|
+
}
|
|
27
|
+
/** A `Result` says by itself whether it refuses; anything else an action returned is a success. */
|
|
28
|
+
function outcomeOf(value, { ran = false } = {}) {
|
|
29
|
+
if (typeof value === 'object' && value !== null && 'ok' in value && typeof value.ok === 'boolean') {
|
|
30
|
+
return value.ok || !('error' in value) ? { refused: false } : { refused: true, error: value.error };
|
|
31
|
+
}
|
|
32
|
+
return ran ? { refused: false } : { refused: true, error: value };
|
|
33
|
+
}
|
|
34
|
+
function refusalOf(attempt, code, facts) {
|
|
35
|
+
if (!attempt.refused) {
|
|
36
|
+
throw failure(`Expected a refusal with code ${code}, but nothing was refused.`, undefined, code);
|
|
37
|
+
}
|
|
38
|
+
const { error } = attempt;
|
|
39
|
+
const actual = codeOf(error);
|
|
40
|
+
if (actual !== code) {
|
|
41
|
+
throw failure(`Expected a refusal with code ${code}, but got ${described(error)}.`, actual, code);
|
|
42
|
+
}
|
|
43
|
+
const mismatches = factMismatches(error, facts);
|
|
44
|
+
if (mismatches.length > 0) {
|
|
45
|
+
throw failure([`The refusal ${code} does not carry the expected facts.`, ...mismatches].join('\n '), error, facts);
|
|
46
|
+
}
|
|
47
|
+
return error;
|
|
48
|
+
}
|
|
49
|
+
function failure(message, actual, expected) {
|
|
50
|
+
return new AssertionError({ message, actual, expected, operator: 'expectRefusal' });
|
|
51
|
+
}
|
|
52
|
+
function codeOf(error) {
|
|
53
|
+
return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string'
|
|
54
|
+
? error.code
|
|
55
|
+
: undefined;
|
|
56
|
+
}
|
|
57
|
+
function described(error) {
|
|
58
|
+
if (!(error instanceof Error)) {
|
|
59
|
+
return show(error);
|
|
60
|
+
}
|
|
61
|
+
const code = codeOf(error);
|
|
62
|
+
return `${error.constructor.name}${code === undefined ? '' : ` (code ${code})`}: ${error.message}`;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=expect-refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect-refusal.js","sourceRoot":"","sources":["../../src/refusals/expect-refusal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expected-facts.d.ts","sourceRoot":"","sources":["../../src/refusals/expected-facts.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expected-facts.js","sourceRoot":"","sources":["../../src/refusals/expected-facts.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ExpectedFacts } from './expected-facts.js';
|
|
2
|
+
/** One sentence per expected fact the error does not carry with that value. */
|
|
3
|
+
export declare function factMismatches(error: unknown, expected: ExpectedFacts): string[];
|
|
4
|
+
//# sourceMappingURL=fact-mismatches.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fact-mismatches.d.ts","sourceRoot":"","sources":["../../src/refusals/fact-mismatches.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAYhF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
2
|
+
import { show } from '../scenarios/show.js';
|
|
3
|
+
/** One sentence per expected fact the error does not carry with that value. */
|
|
4
|
+
export function factMismatches(error, expected) {
|
|
5
|
+
const facts = factsOf(error);
|
|
6
|
+
return Object.entries(expected).flatMap(([name, value]) => {
|
|
7
|
+
if (!(name in facts)) {
|
|
8
|
+
return [`fact ${name}: expected ${show(value)}, the refusal carries no such fact`];
|
|
9
|
+
}
|
|
10
|
+
return isDeepStrictEqual(facts[name], value)
|
|
11
|
+
? []
|
|
12
|
+
: [`fact ${name}: expected ${show(value)}, got ${show(facts[name])}`];
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function factsOf(error) {
|
|
16
|
+
if (typeof error !== 'object' || error === null || !('facts' in error)) {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
const { facts } = error;
|
|
20
|
+
return typeof facts === 'object' && facts !== null ? { ...facts } : {};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=fact-mismatches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fact-mismatches.js","sourceRoot":"","sources":["../../src/refusals/fact-mismatches.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAG5C,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,QAAuB;IACpE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAE7B,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QACxD,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,QAAQ,IAAI,cAAc,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACrF,CAAC;QAED,OAAO,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;YAC1C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,QAAQ,IAAI,cAAc,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC,EAAE,CAAC;QACvE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAExB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACzE,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AsyncOutcome } from './async-outcome.js';
|
|
2
|
+
import type { ExpectedFacts } from '../refusals/expected-facts.js';
|
|
2
3
|
import type { ErrorClass } from './error-class.js';
|
|
3
4
|
import type { EventMatcher } from './event-matcher.js';
|
|
4
5
|
import type { Recorded } from './recorded.js';
|
|
@@ -10,7 +11,7 @@ export declare class DeferredOutcome<A> implements AsyncOutcome<A> {
|
|
|
10
11
|
thenEvents(expected: readonly EventMatcher[]): this;
|
|
11
12
|
thenEventNames(expected: readonly string[]): this;
|
|
12
13
|
thenNoEvent(): this;
|
|
13
|
-
thenError(typeOrCode: ErrorClass | string,
|
|
14
|
+
thenError(typeOrCode: ErrorClass | string, detail?: string | ExpectedFacts): this;
|
|
14
15
|
thenState(inspectState: (aggregate: A) => void): this;
|
|
15
16
|
then<Fulfilled = void, Rejected = never>(onFulfilled?: ((value: undefined) => Fulfilled | PromiseLike<Fulfilled>) | null, onRejected?: ((reason: unknown) => Rejected | PromiseLike<Rejected>) | null): PromiseLike<Fulfilled | Rejected>;
|
|
16
17
|
private after;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deferred-outcome.d.ts","sourceRoot":"","sources":["../../src/scenarios/deferred-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,uGAAuG;AACvG,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IAKpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ5C,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAE/D;IAED,OAAO,eAAuE;IAE9E,UAAU,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAElD;IAED,cAAc,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAEhD;IAED,WAAW,IAAI,IAAI,CAElB;IAED,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"deferred-outcome.d.ts","sourceRoot":"","sources":["../../src/scenarios/deferred-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,uGAAuG;AACvG,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IAKpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ5C,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAE/D;IAED,OAAO,eAAuE;IAE9E,UAAU,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAElD;IAED,cAAc,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAEhD;IAED,WAAW,IAAI,IAAI,CAElB;IAED,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAEhF;IAED,SAAS,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,CAEpD;IAED,IAAI,CAAC,SAAS,GAAG,IAAI,EAAE,QAAQ,GAAG,KAAK,EACrC,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,EAC/E,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAC1E,WAAW,CAAC,SAAS,GAAG,QAAQ,CAAC,CAEnC;IAED,OAAO,CAAC,KAAK;CAId"}
|
|
@@ -17,8 +17,8 @@ export class DeferredOutcome {
|
|
|
17
17
|
thenNoEvent() {
|
|
18
18
|
return this.after((outcome) => outcome.thenNoEvent());
|
|
19
19
|
}
|
|
20
|
-
thenError(typeOrCode,
|
|
21
|
-
return this.after((outcome) =>
|
|
20
|
+
thenError(typeOrCode, detail) {
|
|
21
|
+
return this.after((outcome) => outcome.thenError(typeOrCode, detail));
|
|
22
22
|
}
|
|
23
23
|
thenState(inspectState) {
|
|
24
24
|
return this.after((outcome) => outcome.thenState(inspectState));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deferred-outcome.js","sourceRoot":"","sources":["../../src/scenarios/deferred-outcome.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deferred-outcome.js","sourceRoot":"","sources":["../../src/scenarios/deferred-outcome.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,uGAAuG;AACvG,MAAM,OAAO,eAAe;IAKW,OAAO;IAJ5C,MAAM,CAAC,EAAE,CAAI,QAA8B;QACzC,OAAO,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,YAAqC,OAAqC;uBAArC,OAAO;IAAiC,CAAC;IAE9E,UAAU,CAAC,QAAiC;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,cAAc,CAAC,QAA2B;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,SAAS,CAAC,UAA+B,EAAE,MAA+B;QACxE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,SAAS,CAAC,YAAoC;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CACF,WAA+E,EAC/E,UAA2E;QAE3E,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IAEO,KAAK,CAAC,MAA6D;QACzE,yKAAyK;QACzK,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAS,CAAC;IAChE,CAAC;CACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ExpectedFacts } from '../refusals/expected-facts.js';
|
|
1
2
|
import type { ErrorClass } from './error-class.js';
|
|
2
3
|
import type { EventMatcher } from './event-matcher.js';
|
|
3
4
|
import type { Outcome } from './outcome.js';
|
|
@@ -10,7 +11,7 @@ export declare class ImmediateOutcome<A> implements Outcome<A> {
|
|
|
10
11
|
thenEvents(expected: readonly EventMatcher[]): this;
|
|
11
12
|
thenEventNames(expected: readonly string[]): this;
|
|
12
13
|
thenNoEvent(): this;
|
|
13
|
-
thenError(typeOrCode: ErrorClass | string,
|
|
14
|
+
thenError(typeOrCode: ErrorClass | string, detail?: string | ExpectedFacts): this;
|
|
14
15
|
thenState(inspectState: (aggregate: A) => void): this;
|
|
15
16
|
private thrownInsteadOf;
|
|
16
17
|
private assertDidNotThrow;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"immediate-outcome.d.ts","sourceRoot":"","sources":["../../src/scenarios/immediate-outcome.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"immediate-outcome.d.ts","sourceRoot":"","sources":["../../src/scenarios/immediate-outcome.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,gFAAgF;AAChF,qBAAa,gBAAgB,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAIxC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,aAAa,CAAS;IAE9B,YAA6B,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAI;IAEtD,UAAU,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CA6BlD;IAED,cAAc,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAkBhD;IAED,WAAW,IAAI,IAAI,CAclB;IAED,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAyBhF;IAED,SAAS,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,CAQpD;IAED,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,iBAAiB;CAY1B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AssertionError } from 'node:assert';
|
|
2
2
|
import { isDeepStrictEqual } from 'node:util';
|
|
3
|
+
import { factMismatches } from '../refusals/fact-mismatches.js';
|
|
3
4
|
import { describeEvent } from './describe-event.js';
|
|
4
5
|
import { eventMismatches } from './event-mismatches.js';
|
|
5
6
|
import { show } from './show.js';
|
|
@@ -66,9 +67,9 @@ export class ImmediateOutcome {
|
|
|
66
67
|
}
|
|
67
68
|
return this;
|
|
68
69
|
}
|
|
69
|
-
thenError(typeOrCode,
|
|
70
|
+
thenError(typeOrCode, detail) {
|
|
70
71
|
const type = typeof typeOrCode === 'string' ? undefined : typeOrCode;
|
|
71
|
-
const expectedCode = typeof typeOrCode === 'string' ? typeOrCode :
|
|
72
|
+
const expectedCode = typeof typeOrCode === 'string' ? typeOrCode : codeIn(detail);
|
|
72
73
|
const expected = [type?.name, expectedCode === undefined ? undefined : `code ${expectedCode}`]
|
|
73
74
|
.filter((part) => part !== undefined)
|
|
74
75
|
.join(' with ');
|
|
@@ -83,6 +84,7 @@ export class ImmediateOutcome {
|
|
|
83
84
|
operator: 'thenError',
|
|
84
85
|
});
|
|
85
86
|
}
|
|
87
|
+
assertFacts(error, typeof detail === 'object' ? detail : {});
|
|
86
88
|
this.errorAsserted = true;
|
|
87
89
|
return this;
|
|
88
90
|
}
|
|
@@ -132,6 +134,20 @@ function describeMatcher(matcher) {
|
|
|
132
134
|
}
|
|
133
135
|
return typeof matcher === 'function' ? `instance of ${matcher.name}` : show(matcher);
|
|
134
136
|
}
|
|
137
|
+
function codeIn(detail) {
|
|
138
|
+
return typeof detail === 'string' ? detail : undefined;
|
|
139
|
+
}
|
|
140
|
+
function assertFacts(error, expected) {
|
|
141
|
+
const mismatches = factMismatches(error, expected);
|
|
142
|
+
if (mismatches.length > 0) {
|
|
143
|
+
throw new AssertionError({
|
|
144
|
+
message: ['The error does not carry the expected facts.', ...section('Difference', mismatches)].join('\n'),
|
|
145
|
+
actual: error,
|
|
146
|
+
expected,
|
|
147
|
+
operator: 'thenError',
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
135
151
|
function codeOf(error) {
|
|
136
152
|
return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string'
|
|
137
153
|
? error.code
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"immediate-outcome.js","sourceRoot":"","sources":["../../src/scenarios/immediate-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"immediate-outcome.js","sourceRoot":"","sources":["../../src/scenarios/immediate-outcome.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ExpectedFacts } from '../refusals/expected-facts.js';
|
|
1
2
|
import type { ErrorClass } from './error-class.js';
|
|
2
3
|
import type { EventMatcher } from './event-matcher.js';
|
|
3
4
|
/** The assertions available once `when` ran. Each returns the outcome, so they chain. */
|
|
@@ -9,8 +10,8 @@ export interface Outcome<A> {
|
|
|
9
10
|
thenNoEvent(): this;
|
|
10
11
|
/** The action threw an instance of `type` (and, when given, with this `code`). */
|
|
11
12
|
thenError(type: ErrorClass, code?: string): this;
|
|
12
|
-
/** The action threw an error carrying this `code`, whatever its class. */
|
|
13
|
-
thenError(code: string): this;
|
|
13
|
+
/** The action threw an error carrying this `code`, whatever its class, and these facts when given. */
|
|
14
|
+
thenError(code: string, facts?: ExpectedFacts): this;
|
|
14
15
|
/** Inspects the aggregate after the action; `inspect` asserts with the runner's own tools. */
|
|
15
16
|
thenState(inspect: (aggregate: A) => void): this;
|
|
16
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../src/scenarios/outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,yFAAyF;AACzF,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,2CAA2C;IAC3C,UAAU,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAAC;IACpD,gDAAgD;IAChD,cAAc,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAClD,WAAW,IAAI,IAAI,CAAC;IACpB,kFAAkF;IAClF,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,
|
|
1
|
+
{"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../src/scenarios/outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,yFAAyF;AACzF,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,2CAA2C;IAC3C,UAAU,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAAC;IACpD,gDAAgD;IAChD,cAAc,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAClD,WAAW,IAAI,IAAI,CAAC;IACpB,kFAAkF;IAClF,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,sGAAsG;IACtG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrD,8FAA8F;IAC9F,SAAS,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CAClD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ddd-ts-kit/testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Readable tests without mocks: test data builders, given/when/then scenarios and contract suites shared by fakes and real adapters.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"dist"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@ddd-ts-kit/kernel": "0.
|
|
49
|
+
"@ddd-ts-kit/kernel": "0.3.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@ddd-ts-kit/aspects": "0.
|
|
53
|
-
"@ddd-ts-kit/events": "0.
|
|
52
|
+
"@ddd-ts-kit/aspects": "0.3.0",
|
|
53
|
+
"@ddd-ts-kit/events": "0.3.0",
|
|
54
54
|
"@faker-js/faker": "^10.6.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|