When expecting against an async function in TypeScript, I find that
expect(fn).toBeFunction();
fails. Delving deeper, it's because the implementation doesn't just do something along the lines of:
assert(typeof(actual) === "function");
(which is how I've implemented toBeFunction before just being lazy and relying on expect-more-jest
). So the typescript test for the above fails because
Object.prototype.toString.call(fn) === "[object AsyncFunction]";
I wrote out the matcher and typings to complete this, in my repo:
import MatchersUtil = jasmine.MatchersUtil;
import CustomEqualityTester = jasmine.CustomEqualityTester;
import CustomMatcherResult = jasmine.CustomMatcherResult;
declare module jest {
interface Matchers<R> {
toBeAsyncFunction<R>(): void;
}
}
function assert(expr, failMessage) {
if (!expr) {
throw new Error(failMessage);
}
}
function runAssertions(func: () => void) {
try {
func();
return {
message: "",
pass: true
};
} catch (e) {
return {
pass: false,
message: e.message || e
};
}
}
jest.addMatchers({
toBeAsyncFunction: function (util: MatchersUtil, customEqualityTester: CustomEqualityTester[]) {
return {
compare: function (actual: any): CustomMatcherResult {
return runAssertions(() =>
assert(Object.prototype.toString.call(actual) === "[object AsyncFunction]",
`expected async function but got ${JSON.stringify(actual)}`)
);
}
};
}
});
Apologies for:
- 4-space indents (it's our chosen company style)
- "convolution" via
assert
and try/catch
-- I expect to add more matchers and have found this to be a relatively simple way to add more matchers
I cloned this repo because I wanted to create a PR for this, but I can't successfully run tests -- npm test
doesn't run for me (**). I'm probably doing something wrong, so I'd appreciate a push in the right direction, in which case, I'll just submit a PR (: In the meantime, .toBeFunction
doesn't appear to recognise async functions correctly.
** What I have tried:
- Originally,
npm test
fails, throwing errors about invalid syntax around import
statements. Replacing the inbuilt transpile-tests.js
by installing ts-jest
and using that instead, fixed that, but then came:
- Tests failing because they can't import
expect-more
. Now, I can see that each item under packages
has its own package.json
, but tests are run in the context of the base package; also, this is a bit of a chicken-and-egg: I can't write tests against the new code without uploading the package, if I'm to expect the import from the expect-more
in each package.json to suffice. I've tried hard-linking the src
folder of package.json
to the node_modules
folder in the base -- which gets tests to run, but many fail (for example isDivisibleBy
fails on typescript errors, saying that isDivisibleBy
should take two arguments -- and afaik, this is the difference between jasmine 1 and 2 tests? Not sure; anyhoo, I'm a bit lost as to the correct way to run tests and there's no point making a PR if I can't even prove that what I've added works :/ But again, given a push in the right direction, I'll gladly have a swing at it.