Skip to content

Commit 390ea01

Browse files
Remove expectThrowsAsync (#277)
* refactor: remove expectThrowsAsync in most places * refactor: simplify expectThrowsRequestErrorAsync * refactor: only await promise once --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 7d482b5 commit 390ea01

File tree

10 files changed

+69
-173
lines changed

10 files changed

+69
-173
lines changed

packages/app-runtime/test/lib/TestUtil.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -135,33 +135,6 @@ export class TestUtil {
135135
}
136136
}
137137

138-
public static async expectThrowsAsync(method: Function | Promise<any>, customExceptionMatcher: (e: Error) => void): Promise<void>;
139-
140-
public static async expectThrowsAsync(method: Function | Promise<any>, errorMessageRegexp: RegExp | string): Promise<void>;
141-
142-
public static async expectThrowsAsync(method: Function | Promise<any>, errorMessageRegexp: RegExp | string | ((e: Error) => void)): Promise<void> {
143-
let error: Error | undefined;
144-
try {
145-
if (typeof method === "function") {
146-
await method();
147-
} else {
148-
await method;
149-
}
150-
} catch (err: any) {
151-
error = err;
152-
}
153-
expect(error).toBeInstanceOf(Error);
154-
155-
if (typeof errorMessageRegexp === "function") {
156-
errorMessageRegexp(error!);
157-
return;
158-
}
159-
160-
if (errorMessageRegexp) {
161-
expect(error!.message).toMatch(new RegExp(errorMessageRegexp));
162-
}
163-
}
164-
165138
public static async provideAccounts(runtime: AppRuntime, count: number): Promise<LocalAccountDTO[]> {
166139
const accounts: LocalAccountDTO[] = [];
167140

packages/consumption/test/core/TestUtil.ts

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -103,45 +103,6 @@ export class TestUtil {
103103
expect(error!.message).toMatch(new RegExp(errorMessageRegexp));
104104
}
105105

106-
public static async expectThrowsAsync(method: Function | Promise<any>, customExceptionMatcher?: (e: Error) => void): Promise<void>;
107-
public static async expectThrowsAsync(method: Function | Promise<any>, errorMessagePatternOrRegexp: RegExp): Promise<void>;
108-
/**
109-
*
110-
* @param method The function which should throw the exception
111-
* @param errorMessagePattern the pattern the error message should match (asterisks ('\*') are wildcards that correspond to '.\*' in regex)
112-
*/
113-
public static async expectThrowsAsync(method: Function | Promise<any>, errorMessagePattern: string): Promise<void>;
114-
115-
public static async expectThrowsAsync(method: Function | Promise<any>, errorMessageRegexp: RegExp | string | ((e: Error) => void) | undefined): Promise<void> {
116-
let error: Error | undefined;
117-
try {
118-
if (typeof method === "function") {
119-
await method();
120-
} else {
121-
await method;
122-
}
123-
} catch (err: unknown) {
124-
if (!(err instanceof Error)) throw err;
125-
126-
error = err;
127-
}
128-
129-
expect(error).toBeInstanceOf(Error);
130-
131-
if (!errorMessageRegexp) return;
132-
133-
if (typeof errorMessageRegexp === "function") {
134-
errorMessageRegexp(error!);
135-
return;
136-
}
137-
138-
if (typeof errorMessageRegexp === "string") {
139-
errorMessageRegexp = new RegExp(errorMessageRegexp.replaceAll("*", ".*"));
140-
}
141-
142-
expect(error!.message).toMatch(new RegExp(errorMessageRegexp));
143-
}
144-
145106
public static async createConnection(): Promise<IDatabaseConnection> {
146107
let dbConnection;
147108
if (process.env.USE_LOKIJS === "true") {

packages/consumption/test/modules/attributes/AttributesController.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,8 +2457,7 @@ describe("AttributesController", function () {
24572457
})
24582458
});
24592459

2460-
await TestUtil.expectThrowsAsync(
2461-
appConsumptionController.attributes.setAsDefaultRepositoryAttribute(sharedAttribute),
2460+
await expect(appConsumptionController.attributes.setAsDefaultRepositoryAttribute(sharedAttribute)).rejects.toThrow(
24622461
"error.consumption.attributes.isNotRepositoryAttribute"
24632462
);
24642463
});
@@ -2475,8 +2474,7 @@ describe("AttributesController", function () {
24752474
});
24762475
expect(repositoryAttribute.isDefault).toBeUndefined();
24772476

2478-
await TestUtil.expectThrowsAsync(
2479-
consumptionController.attributes.setAsDefaultRepositoryAttribute(repositoryAttribute),
2477+
await expect(consumptionController.attributes.setAsDefaultRepositoryAttribute(repositoryAttribute)).rejects.toThrow(
24802478
"error.consumption.attributes.setDefaultRepositoryAttributesIsDisabled"
24812479
);
24822480
});
@@ -2864,7 +2862,7 @@ describe("AttributesController", function () {
28642862
});
28652863

28662864
test("should throw if an unassigned attribute id is queried", async function () {
2867-
await TestUtil.expectThrowsAsync(consumptionController.attributes.getVersionsOfAttribute(CoreId.from("ATTxxxxxxxxxxxxxxxxx")), "error.transport.recordNotFound");
2865+
await expect(consumptionController.attributes.getVersionsOfAttribute(CoreId.from("ATTxxxxxxxxxxxxxxxxx"))).rejects.toThrow("error.transport.recordNotFound");
28682866
});
28692867

28702868
test("should check if two attributes are subsequent in succession", async function () {
@@ -3052,7 +3050,7 @@ describe("AttributesController", function () {
30523050
});
30533051

30543052
test("should throw if an unassigned attribute id is queried", async function () {
3055-
await TestUtil.expectThrowsAsync(consumptionController.attributes.getSharedVersionsOfAttribute(CoreId.from("ATTxxxxxxxxxxxxxxxxx")), "error.transport.recordNotFound");
3053+
await expect(consumptionController.attributes.getSharedVersionsOfAttribute(CoreId.from("ATTxxxxxxxxxxxxxxxxx"))).rejects.toThrow("error.transport.recordNotFound");
30563054
});
30573055

30583056
test("should return an empty list if a shared identity attribute is queried", async function () {

packages/consumption/test/modules/requests/RequestsIntegrationTest.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,13 +1171,12 @@ export class RequestsThen {
11711171
}
11721172

11731173
public async itThrowsAnErrorWithTheErrorMessage(errorMessage: string): Promise<void> {
1174-
await TestUtil.expectThrowsAsync(this.context.actionToTry!, errorMessage);
1174+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
1175+
await expect(this.context.actionToTry!).rejects.toThrow(regex);
11751176
}
11761177

11771178
public async itThrowsAnErrorWithTheErrorCode(code: string): Promise<void> {
1178-
await TestUtil.expectThrowsAsync(this.context.actionToTry!, (error: Error) => {
1179-
expect((error as any).code).toStrictEqual(code);
1180-
});
1179+
await expect(this.context.actionToTry!).rejects.toThrow(code);
11811180
}
11821181

11831182
public eventHasBeenPublished<TEvent extends DataEvent<unknown>>(

packages/content/test/requests/Request.test.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Serializable, type } from "@js-soft/ts-serval";
22
import { CoreDate, CoreId } from "@nmshd/core-types";
33
import { IRequest, IRequestItem, IRequestItemGroup, Request, RequestItem, RequestItemGroup, RequestItemGroupJSON, RequestItemJSON, RequestJSON } from "../../src";
4-
import { expectThrowsAsync } from "../testUtils";
54

65
interface TestRequestItemJSON extends RequestItemJSON {
76
"@type": "TestRequestItem";
@@ -127,16 +126,19 @@ describe("Request", function () {
127126
expect(serializedRequest).toStrictEqual(requestJSON);
128127
});
129128

130-
test("must have at least one item", async function () {
129+
test("must have at least one item", function () {
131130
const requestJSON = {
132131
"@type": "Request",
133132
items: []
134133
} as RequestJSON;
135134

136-
await expectThrowsAsync(() => Request.from(requestJSON), "*Request.items*may not be empty");
135+
const errorMessage = "*Request.items*may not be empty";
136+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
137+
138+
expect(() => Request.from(requestJSON)).toThrow(regex);
137139
});
138140

139-
test("groups must have at least one item", async function () {
141+
test("groups must have at least one item", function () {
140142
const requestJSON = {
141143
"@type": "Request",
142144
id: "CNSREQ1",
@@ -149,10 +151,13 @@ describe("Request", function () {
149151
]
150152
} as RequestJSON;
151153

152-
await expectThrowsAsync(() => Request.from(requestJSON), "*RequestItemGroup.items*may not be empty*");
154+
const errorMessage = "*RequestItemGroup.items*may not be empty*";
155+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
156+
157+
expect(() => Request.from(requestJSON)).toThrow(regex);
153158
});
154159

155-
test("mustBeAccepted is mandatory", async function () {
160+
test("mustBeAccepted is mandatory", function () {
156161
const requestJSON = {
157162
"@type": "Request",
158163
items: [
@@ -162,6 +167,9 @@ describe("Request", function () {
162167
]
163168
} as RequestJSON;
164169

165-
await expectThrowsAsync(() => Serializable.fromUnknown(requestJSON), "TestRequestItem.mustBeAccepted*Value is not defined");
170+
const errorMessage = "TestRequestItem.mustBeAccepted*Value is not defined";
171+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
172+
173+
expect(() => Serializable.fromUnknown(requestJSON)).toThrow(regex);
166174
});
167175
});

packages/content/test/requests/Response.test.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
ResponseJSON,
1919
ResponseResult
2020
} from "../../src";
21-
import { expectThrowsAsync } from "../testUtils";
2221

2322
interface ITestAcceptResponseItem extends IAcceptResponseItem {
2423
test: string;
@@ -141,18 +140,21 @@ describe("Response", function () {
141140
expect(serializedRequest).toStrictEqual(responseJSON);
142141
});
143142

144-
test("must have at least one item", async function () {
143+
test("must have at least one item", function () {
145144
const responseJSON = {
146145
"@type": "Response",
147146
result: ResponseResult.Accepted,
148147
requestId: "CNSREQ1",
149148
items: []
150149
} as ResponseJSON;
151150

152-
await expectThrowsAsync(() => Response.from(responseJSON), "*Response.items*may not be empty*");
151+
const errorMessage = "*Response.items*may not be empty*";
152+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
153+
154+
expect(() => Response.from(responseJSON)).toThrow(regex);
153155
});
154156

155-
test("groups must have at least one item", async function () {
157+
test("groups must have at least one item", function () {
156158
const responseJSON = {
157159
"@type": "Response",
158160
result: ResponseResult.Accepted,
@@ -165,7 +167,10 @@ describe("Response", function () {
165167
]
166168
} as ResponseJSON;
167169

168-
await expectThrowsAsync(() => Response.from(responseJSON), "*ResponseItemGroup.items*may not be empty*");
170+
const errorMessage = "*ResponseItemGroup.items*may not be empty*";
171+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
172+
173+
expect(() => Response.from(responseJSON)).toThrow(regex);
169174
});
170175

171176
test("allows an inherited AcceptResponseItem in the items", function () {
@@ -196,7 +201,7 @@ describe("Response", function () {
196201
});
197202

198203
describe("Throws an error when a mandatory property is missing", function () {
199-
test("throws on missing requestId", async function () {
204+
test("throws on missing requestId", function () {
200205
const responseJSON = {
201206
"@type": "Response",
202207
result: ResponseResult.Accepted,
@@ -208,10 +213,13 @@ describe("Response", function () {
208213
]
209214
} as ResponseJSON;
210215

211-
await expectThrowsAsync(() => Response.from(responseJSON), "*Response.requestId*Value is not defined*");
216+
const errorMessage = "*Response.requestId*Value is not defined*";
217+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
218+
219+
expect(() => Response.from(responseJSON)).toThrow(regex);
212220
});
213221

214-
test("throws on missing response item status", async function () {
222+
test("throws on missing response item status", function () {
215223
const responseJSON = {
216224
"@type": "Response",
217225
result: ResponseResult.Accepted,
@@ -223,10 +231,13 @@ describe("Response", function () {
223231
]
224232
} as ResponseJSON;
225233

226-
await expectThrowsAsync(() => Response.from(responseJSON), "*ResponseItem.result*Value is not defined*");
234+
const errorMessage = "*ResponseItem.result*Value is not defined*";
235+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
236+
237+
expect(() => Response.from(responseJSON)).toThrow(regex);
227238
});
228239

229-
test("throws on missing error response content properties", async function () {
240+
test("throws on missing error response content properties", function () {
230241
const jsonWithMissingErrorCode = {
231242
"@type": "Response",
232243
result: ResponseResult.Accepted,
@@ -240,10 +251,13 @@ describe("Response", function () {
240251
]
241252
} as ResponseJSON;
242253

243-
await expectThrowsAsync(() => Response.from(jsonWithMissingErrorCode), "*ErrorResponseItem.code*Value is not defined*");
254+
const errorMessage = "*ErrorResponseItem.code*Value is not defined*";
255+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
256+
257+
expect(() => Response.from(jsonWithMissingErrorCode)).toThrow(regex);
244258
});
245259

246-
test("error response content message is mandatory", async function () {
260+
test("error response content message is mandatory", function () {
247261
const jsonWithMissingErrorCode: ResponseJSON = {
248262
"@type": "Response",
249263
result: ResponseResult.Accepted,
@@ -257,7 +271,10 @@ describe("Response", function () {
257271
]
258272
};
259273

260-
await expectThrowsAsync(() => Response.from(jsonWithMissingErrorCode), "*ErrorResponseItem.message*Value is not defined*");
274+
const errorMessage = "*ErrorResponseItem.message*Value is not defined*";
275+
const regex = new RegExp(errorMessage.replace(/\*/g, ".*"));
276+
277+
expect(() => Response.from(jsonWithMissingErrorCode)).toThrow(regex);
261278
});
262279
});
263280
});

packages/content/test/testUtils.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,3 @@ export function expectThrows(method: Function, errorMessage = ""): void {
1616
expect(error!.message, `Error Message: ${error!.message}`).toMatch(new RegExp(`^${errorMessage}`));
1717
}
1818
}
19-
20-
export async function expectThrowsAsync(method: Function | Promise<any>, customExceptionMatcher?: (e: Error) => void): Promise<void>;
21-
22-
export async function expectThrowsAsync(method: Function | Promise<any>, errorMessagePatternOrRegexp: RegExp): Promise<void>;
23-
24-
/**
25-
*
26-
* @param method The function which should throw the exception
27-
* @param errorMessagePattern the pattern the error message should match (asterisks ('\*') are wildcards that correspond to '.\*' in regex)
28-
*/
29-
export async function expectThrowsAsync(method: Function | Promise<any>, errorMessagePattern: string): Promise<void>;
30-
31-
export async function expectThrowsAsync(method: Function | Promise<any>, errorMessageRegexp: RegExp | string | ((e: Error) => void) | undefined): Promise<void> {
32-
let error: Error | undefined;
33-
try {
34-
if (typeof method === "function") {
35-
await method();
36-
} else {
37-
await method;
38-
}
39-
} catch (err: unknown) {
40-
if (!(err instanceof Error)) throw err;
41-
42-
error = err;
43-
}
44-
45-
expect(error, "Expected an error to be thrown").toBeInstanceOf(Error);
46-
47-
if (!errorMessageRegexp) return;
48-
49-
if (typeof errorMessageRegexp === "function") {
50-
errorMessageRegexp(error!);
51-
return;
52-
}
53-
54-
if (typeof errorMessageRegexp === "string") {
55-
errorMessageRegexp = new RegExp(errorMessageRegexp.replaceAll("*", ".*"));
56-
}
57-
58-
expect(error!.message).toMatch(new RegExp(errorMessageRegexp));
59-
}

packages/transport/test/modules/devices/DeviceOnboarding.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ describe("Device Onboarding", function () {
169169
test("should have changed the password of the created device (backbone)", async function () {
170170
TestUtil.useFatalLoggerFactory();
171171

172-
await TestUtil.expectThrowsAsync(async () => {
172+
await expect(async () => {
173173
await deviceTest.onboardDevice(sharedSecret);
174-
}, "error.transport.request.noAuthGrant");
174+
}).rejects.toThrow("error.transport.request.noAuthGrant");
175175
});
176176
});

packages/transport/test/modules/relationshipTemplates/RelationshipTemplateController.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ describe("RelationshipTemplateController", function () {
106106
});
107107

108108
test("should throw an error with maxNumberOfAllocations=0", async function () {
109-
await TestUtil.expectThrowsAsync(async () => {
109+
await expect(async () => {
110110
await sender.relationshipTemplates.sendRelationshipTemplate({
111111
content: { a: "A" },
112112
expiresAt: CoreDate.utc().add({ minutes: 1 }),
113113
maxNumberOfAllocations: 0
114114
});
115-
}, /SendRelationshipTemplateParameters.maxNumberOfAllocations/);
115+
}).rejects.toThrow(/SendRelationshipTemplateParameters.maxNumberOfAllocations/);
116116
});
117117

118118
test("should send and receive a RelationshipTemplate using a RelationshipTemplateReference", async function () {

0 commit comments

Comments
 (0)