-
-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reintroduce asserting types when values are uncertain #484
Comments
After investigating other options it looks like I can also produce the desired result with: type Shape = typeof data;
const data = {
str: "abc",
bool: true,
num: 123,
obj: {},
};
expect(data).toMatchObject<Shape>({
str: expect.any(String) as string,
bool: expect.any(Boolean) as boolean,
num: expect.any(Number) as number,
obj: expect.any(Object) as object,
}); Which is an improvement in the right direction. Would it be possible to detect the correct type from the passed in |
This is an unusual way to use I'd think a better test would be type Shape = {
str: String,
bool: boolean,
num: Number,
obj: Object,
};
const data = {
str: "abc",
bool: true,
num: 123,
obj: {},
};
expect(obj instanceof Shape).toBeTrue(); If I understood the use case better, maybe I could suggest a better option. I made the change to add the |
The previous usage was very versatile because you could match some of the properties on an object with their respective values, and where you didn't know the value you could pass the expect.toBeType(), thirdly you could pass a expect(data).toMatchObject({
cat: "dog",
hello: expect.stringMatching(/, world$/),
foo: true,
colors: expect.toBeArray(),
age: expect.toBeNumber(),
}); |
The only reason such a usage worked before was because it was using an Generifying functions like |
I'll discuss with the other maintainers about the return type we have now compared to |
The explicit types are technically correct, but as far as I am aware, not useful for the consumers of jest-extended. There may be use cases that I'm not familiar with. You don't need to actually return a string to say that the type returned is a string. It's sloppy but extremely convenient, and would probably likely result in fewer bugs for end users because casting to any/unknown totally destroys any type information. Thanks! |
It might be useful when creating a new matcher that uses other matchers in its implementation or when unit testing said new matcher. Or just to have autocompletion, should you have any reason to look at the result. What we're talking about is really whether jest-extended itself should lose the type information or whether the user's project using it should. I'm not really seeing a good reason to do the former. @SimenB any thoughts here? |
Actually, I was looking at the runtime return type // test Jest matcher
const result1 = expect('2').toBeDefined();
console.log(result1); // prints undefined
// test jest-extended matcher
const result2 = expect('2').toBeString();
console.log(result2); // prints undefined And both were undefined. I think I was confused between the return type of the matcher and the return type of the expect call. I'm now thinking I should change this. Jest's |
Note that DT is not the source of truth - Jest itself should be. And in Jest they don't return
|
I thought about returning |
Hi @keeganwitt , are you planning to open a PR as you mentioned in your last comment? |
Just adding some thoughts to this thread as well: the change to expect(something).toEqual({
// ...
createdAt: expect.toBeDateString() as string,
expiryTime: expect.toBeDateString() as string,
}); Since this PR is merged we need to add the
We don't really want to disable that rule (even in test-code), so I would also be in favour returning at least something not |
Thank you for the reminder. PR here: #535 |
I'm thinking the |
Right, this issue got a bit off my radar, but since updating to the version that included #535, it popped up again :-) For us - for most cases - const actual = {
date: new Date().toString(),
};
expect(actual).toEqual({
date: expect.toBeDateString(),
}); There are a few cases where the expected object is also typed, most notably in mocked
This fails on As a response to you saying 'the runtime type is void': this seems a bit simplistic. Jest does quite some magic behind the scenes and how you are using it gives different results. Compare: describe('foo', () => {
it('should foo', () => {
const actual = {
date: new Date().toString(),
};
const expected = {
date: expect.toBeDateString(),
};
console.log('expected', expected);
expect(actual).toEqual(expected);
});
it('should bar', () => {
const actual = new Date().toString();
const result = expect(actual).toBeDateString();
console.log('result', result);
});
});
So at least it should be I'm not entirely sure if I'm really asking for a change though. This is better than ¹ I understand that this feels a bit convoluted (to explicitly type the argument of the mock). If we just let it be inferred, it's all fine. However there is a library that we are using (https://github.com/m-radzikowski/aws-sdk-client-mock) that provides these kind of typed mocks, so this is where we are running into it. |
I think test('check expect returns undefined', () => {
const toBeStringResult = expect('').toBeString();
expect(toBeStringResult).toBeUndefined();
const toBeDateStringResult = expect('2020-01-01').toBeDateString();
expect(toBeDateStringResult).toBeUndefined();
}); Your use case is creating an expected object with a matcher in it, which is a different usage. I'll study how |
I'm not sure if this belongs under bugs or a feature, but in version 1, it was possible to use jest-extended matches in
toMatchObject
to match by type like so:Since the introduction of the
Result
type, this is now throwing a warning in Typescript:Is it possible to reintroduce this functionality with the addition of generics for asserting the type passed in (removing the need to assert with
as string / boolean / number
),i.e:
The text was updated successfully, but these errors were encountered: