Skip to content

Commit a93e415

Browse files
authored
Merge pull request #12338 from CesiumGS/dev-error-matchers
Allow DeveloperError Jasmine matchers to accept regex for messages
2 parents 2647b90 + 26c7ffa commit a93e415

File tree

6 files changed

+50
-20
lines changed

6 files changed

+50
-20
lines changed

Documentation/Contributors/TestingGuide/README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,22 +441,34 @@ In addition to testing success cases, we also test all failure cases. The custom
441441
```javascript
442442
it("fromDegrees throws with no latitude", function () {
443443
expect(function () {
444-
Cartesian3.fromDegrees(0.0);
445-
}).toThrowDeveloperError();
444+
Cartesian3.fromDegrees(0.0, undefined);
445+
}).toThrowDeveloperError(
446+
"Expected latitude to be typeof number, actual typeof was undefined",
447+
);
446448
});
447449
```
448450

449451
Above, `Cartesian3.fromDegrees` is expected to throw a `DeveloperError` because it expects longitude and latitude arguments, and only longitude is provided.
450452

451-
Tips:
453+
#### Tips
454+
455+
- When testing for exceptions it is recommended to test for the expected error message to verify that the test is triggering the correct error. This can be achieved either with the full error message, like above, or with a regular expression that will match the error message like this:
456+
457+
```javascript
458+
it("fromDegrees throws with no latitude", function () {
459+
expect(function () {
460+
Cartesian3.fromDegrees(0.0, undefined);
461+
}).toThrowDeveloperError(/Expected latitude to be/);
462+
});
463+
```
452464

453465
- When testing for exceptions, put only code that is expected to trigger the exception inside the function passed to `expect()`, in case setup code unintentionally throws an exception.
454466
- To verify the right exception is thrown, it is often useful to comment out the `expect` call when first running the test, for example:
455467

456468
```javascript
457469
it("fromDegrees throws with no latitude", function () {
458470
// expect(function() {
459-
Cartesian3.fromDegrees(0.0);
471+
Cartesian3.fromDegrees(0.0, undefined);
460472
// }).toThrowDeveloperError();
461473
});
462474
```

Specs/addDefaultMatchers.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ function makeAsyncThrowFunction(debug, Type, name) {
4646
.catch((e) => {
4747
let result = e instanceof Type || e.name === name;
4848
if (defined(message)) {
49-
result = result && util.equals(e.message, message);
49+
if (typeof message === "string") {
50+
result = result && e.message === message;
51+
} else {
52+
// if the expected message is a regular expression check it against the error message
53+
// this matches how the builtin .toRejectWithError(Error, /message/) works
54+
// https://github.com/jasmine/jasmine/blob/main/src/core/matchers/toThrowError.js
55+
result = result && message.test(e.message);
56+
}
5057
}
5158
return {
5259
pass: result,
@@ -92,7 +99,7 @@ function makeThrowFunction(debug, Type, name) {
9299
if (debug) {
93100
return function (util) {
94101
return {
95-
compare: function (actual, expected) {
102+
compare: function (actual, message) {
96103
// based on the built-in Jasmine toThrow matcher
97104
let result = false;
98105
let exception;
@@ -110,20 +117,29 @@ function makeThrowFunction(debug, Type, name) {
110117
if (exception) {
111118
result = exception instanceof Type || exception.name === name;
112119
}
120+
if (defined(message)) {
121+
if (typeof message === "string") {
122+
result = result && exception.message === message;
123+
} else {
124+
// if the expected message is a regular expression check it against the error message
125+
// this matches how the builtin .toRejectWithError(Error, /message/) works
126+
// https://github.com/jasmine/jasmine/blob/main/src/core/matchers/toThrowError.js
127+
result = result && message.test(exception.message);
128+
}
129+
}
113130

114-
let message;
131+
let testMessage;
115132
if (result) {
116-
message = [
117-
`Expected function not to throw ${name} , but it threw`,
118-
exception.message || exception,
119-
].join(" ");
133+
testMessage = `Expected function not to throw ${name} , but it threw ${exception.message || exception}`;
120134
} else {
121-
message = `Expected function to throw ${name}.`;
135+
testMessage = defined(message)
136+
? `Expected to throw with ${name}: ${message}, but it was thrown with ${exception}`
137+
: `Expected function to throw with ${name}.`;
122138
}
123139

124140
return {
125141
pass: result,
126-
message: message,
142+
message: testMessage,
127143
};
128144
},
129145
};

packages/engine/Specs/Core/Cartesian3Spec.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,14 +1241,16 @@ describe("Core/Cartesian3", function () {
12411241

12421242
it("fromDegrees throws with no longitude", function () {
12431243
expect(function () {
1244-
Cartesian3.fromDegrees();
1245-
}).toThrowDeveloperError();
1244+
Cartesian3.fromDegrees(undefined, undefined);
1245+
}).toThrowDeveloperError(/Expected longitude to be/);
12461246
});
12471247

12481248
it("fromDegrees throws with no latitude", function () {
12491249
expect(function () {
1250-
Cartesian3.fromDegrees(1);
1251-
}).toThrowDeveloperError();
1250+
Cartesian3.fromDegrees(1, undefined);
1251+
}).toThrowDeveloperError(
1252+
"Expected latitude to be typeof number, actual typeof was undefined",
1253+
);
12521254
});
12531255

12541256
it("fromDegrees works works with default ellipsoid", function () {

packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () {
155155
it("fromMetadata throws without metadata", function () {
156156
expect(() =>
157157
GoogleEarthEnterpriseImageryProvider.fromMetadata(),
158-
).toThrowDeveloperError("");
158+
).toThrowDeveloperError(/metadata is required/);
159159
});
160160

161161
it("fromMetadata throws if there isn't imagery", async function () {

packages/engine/Specs/Scene/ImageryLayerSpec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ describe(
7878

7979
it("fromProviderAsync throws without provider promise", function () {
8080
expect(() => ImageryLayer.fromProviderAsync()).toThrowDeveloperError(
81-
"expected",
81+
/Expected imageryProviderPromise to be typeof object/,
8282
);
8383
});
8484

packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe("Scene/MapboxStyleImageryProvider", function () {
3131
it("requires the styleId to be specified", function () {
3232
expect(function () {
3333
return new MapboxStyleImageryProvider({ accessToken: "test-token" });
34-
}).toThrowDeveloperError("styleId is required");
34+
}).toThrowDeveloperError("options.styleId is required.");
3535
});
3636

3737
it("returns valid value for hasAlphaChannel", function () {

0 commit comments

Comments
 (0)