Skip to content

Commit 5997541

Browse files
committed
Add ability to use error factory in matcher. Add jest tests for the matcher.
1 parent 92cef94 commit 5997541

File tree

7 files changed

+816
-575
lines changed

7 files changed

+816
-575
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ dist
102102

103103
# TernJS port file
104104
.tern-port
105+
106+
.idea/

jest.config.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
5+
};

package.json

+7-6
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
"scripts": {
2525
"build": "rm -rf ./dist; tsc",
2626
"lint:check": "eslint . --ext .ts",
27-
"lint": "yarn lint:check --fix"
27+
"lint": "yarn lint:check --fix",
28+
"test": "yarn jest --no-colors"
2829
},
2930
"devDependencies": {
30-
"@types/jest": "^25.2.1",
31+
"@types/jest": "^25.2.3",
32+
"@types/node": "^13.13.0",
3133
"@typescript-eslint/eslint-plugin": "^2.28.0",
3234
"@typescript-eslint/parser": "^2.28.0",
3335
"eslint": "^6.8.0",
@@ -37,10 +39,9 @@
3739
"eslint-plugin-node": "^11.1.0",
3840
"eslint-plugin-prettier": "^3.1.3",
3941
"eslint-plugin-simple-import-sort": "^5.0.2",
40-
"jest": "^25.4.0",
42+
"jest": "^26.0.1",
4143
"prettier": "^2.0.4",
42-
"ts-jest": "^25.4.0",
43-
"typescript": "^3.8.3",
44-
"@types/node": "^13.13.0"
44+
"ts-jest": "^26.0.0",
45+
"typescript": "^3.8.3"
4546
}
4647
}

src/matcher.ts

+39-18
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,56 @@ function errorToObject(error: Error) {
1111
};
1212
}
1313

14+
type ErrorFactory = Error | (() => void);
15+
function unwrapErrorFactory(value: ErrorFactory): Error | undefined {
16+
if (typeof value === 'function') {
17+
try {
18+
value();
19+
} catch(error) {
20+
return error;
21+
}
22+
} else {
23+
return value;
24+
}
25+
}
26+
1427
export function toMatchError(
1528
this: MatcherContext,
16-
gotError: Error,
29+
gotErrorFactory: Error | (() => void),
1730
expectedError: Error
1831
): CustomMatcherResult {
19-
const got = errorToObject(gotError);
32+
const gotError = unwrapErrorFactory(gotErrorFactory);
2033
const expected = errorToObject(expectedError);
2134

2235
const diff: string[] = [];
23-
24-
if (got.class !== expected.class) {
36+
if (gotError === undefined) {
2537
diff.push(
26-
"Error class is not the same:",
27-
this.utils.diff(got.class, expected.class) as string
38+
"Expected to receive an error, but no error was thrown"
2839
);
29-
}
40+
} else {
3041

31-
if (got.message !== expected.message) {
32-
diff.push(
33-
"Error message is not the same:",
34-
this.utils.diff(got.message, expected.message) as string
35-
);
36-
}
42+
const got = errorToObject(gotError);
3743

38-
if (!this.equals(got.publicFields, expected.publicFields)) {
39-
diff.push(
40-
"Error public fields is not the same:",
41-
this.utils.diff(got.publicFields, expected.publicFields) as string
42-
);
44+
if (got.class !== expected.class) {
45+
diff.push(
46+
"Error class is not the same:",
47+
this.utils.diff(got.class, expected.class) as string
48+
);
49+
}
50+
51+
if (got.message !== expected.message) {
52+
diff.push(
53+
"Error message is not the same:",
54+
this.utils.diff(got.message, expected.message) as string
55+
);
56+
}
57+
58+
if (!this.equals(got.publicFields, expected.publicFields)) {
59+
diff.push(
60+
"Error public fields is not the same:",
61+
this.utils.diff(got.publicFields, expected.publicFields) as string
62+
);
63+
}
4364
}
4465

4566
return {
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`matcher error factory should fail if no error is thrown 1`] = `"Expected to receive an error, but no error was thrown"`;
4+
5+
exports[`matcher error factory should throw error if different messages 1`] = `
6+
"Error message is not the same:
7+
- Expected
8+
+ Received
9+
10+
- test
11+
+ test2"
12+
`;
13+
14+
exports[`matcher error factory should throw error if different properties 1`] = `
15+
"Error public fields is not the same:
16+
- Expected
17+
+ Received
18+
19+
Object {
20+
- \\"other\\": Object {},
21+
+ \\"other\\": false,
22+
}"
23+
`;
24+
25+
exports[`matcher error factory should throw error if different types 1`] = `
26+
"Error class is not the same:
27+
- Expected
28+
+ Received
29+
30+
- [Function SpecificError2]
31+
+ [Function SpecificError]"
32+
`;
33+
34+
exports[`matcher rejected promises should throw an error if error factory result does not match 1`] = `
35+
"Error class is not the same:
36+
- Expected
37+
+ Received
38+
39+
- [Function SpecificError]
40+
+ [Function SpecificError2]"
41+
`;

test/matcher.test.ts

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import "../src";
2+
3+
class SpecificError extends Error {
4+
constructor(message: string, readonly other: any = {}) {
5+
super(message);
6+
}
7+
}
8+
9+
class SpecificError2 extends Error {
10+
constructor(message: string, readonly other: any = {}) {
11+
super(message);
12+
}
13+
}
14+
15+
function throwError(err: Error) {
16+
return () => {
17+
throw err;
18+
};
19+
}
20+
21+
describe("matcher", () => {
22+
describe("error factory", () => {
23+
it("should be successful if the error factory result matches", () => {
24+
expect(throwError(new SpecificError("test"))).toMatchError(
25+
new SpecificError("test")
26+
);
27+
});
28+
29+
it("should throw error if different types", () => {
30+
expect(() => {
31+
expect(throwError(new SpecificError2("test"))).toMatchError(
32+
new SpecificError("test")
33+
);
34+
}).toThrowErrorMatchingSnapshot();
35+
});
36+
37+
it("should throw error if different messages", () => {
38+
expect(() => {
39+
expect(throwError(new SpecificError("test"))).toMatchError(
40+
new SpecificError("test2")
41+
);
42+
}).toThrowErrorMatchingSnapshot();
43+
});
44+
45+
it("should throw error if different properties", () => {
46+
expect(() => {
47+
expect(throwError(new SpecificError("test"))).toMatchError(
48+
new SpecificError("test", false)
49+
);
50+
}).toThrowErrorMatchingSnapshot();
51+
});
52+
53+
it("should fail if no error is thrown", () => {
54+
expect(() => {
55+
expect(() => true).toMatchError(new SpecificError("test"));
56+
}).toThrowErrorMatchingSnapshot();
57+
});
58+
});
59+
60+
describe("rejected promises", () => {
61+
it("should be successful if the error factory result matches", async () => {
62+
await expect(
63+
Promise.reject(new SpecificError("test"))
64+
).rejects.toMatchError(new SpecificError("test"));
65+
});
66+
67+
it("should throw an error if error factory result does not match", async () => {
68+
await expect(async () => {
69+
await expect(
70+
Promise.reject(new SpecificError("test"))
71+
).rejects.toMatchError(new SpecificError2("test"));
72+
}).rejects.toThrowErrorMatchingSnapshot();
73+
});
74+
});
75+
});

0 commit comments

Comments
 (0)