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
Add a matcher to test decorator applicability #97
Comments
I didn't know about TSTyche so thanks for the ping (and knowing that it works with TSTyche makes me hopeful it can be made to work with tsd too). Regarding your |
Thanks for good questions. To be honest I have zero experience with decorators, so implementing a matcher is a chance to learn something new. As you propose, it sounds good to take second optional argument expect(bound).type.toBeApplicableTo(Person, "greet");
expect(bound).type.toBeApplicableTo(Person, "#sleep"); I don’t see how else a private field like Regarding tsd. I would say that de facto it is an abandoned project, unfortunately. Owners / maintainers do almost nothing with it for years. If you look at last commits, these are mostly new error codes added by contributors. The maintainers merge those without asking to included tests. And so on. Maybe some magic will happen with tsdjs/tsd#196, but it also looks rather forgotten. |
Ah.. static and non-static members with the same name is great edge case. Looks simple on surface: class Foo {
static bar() {
return "xyz";
}
bar() {
return 123;
}
}
expect(bound).type.toBeApplicableTo(Foo.bar); // static method
expect(bound).type.toBeApplicableTo(Foo, "bar"); // same as '.toBeApplicableTo(Foo.prototype.bar)'. But it is allowed to have expect(bound).type.toBeApplicableTo(Foo, "bar"); // the default hint is "instance"
expect(bound).type.toBeApplicableTo(Foo, "bar", "static"); |
What if this matcher would be a decorator? import { expect } from "tstyche";
import { bound, collector, selector, unbound } from "../decorators.js";
@expect(collector).type.toBeApplicable // looks good here
@expect(selector).type.not.toBeApplicable
class Fixture {
#name: string;
constructor(name: string) {
this.#name = name;
}
@expect(bound).type.toBeApplicable // works with any field kind
@expect(unbound).type.not.toBeApplicable
greet() {
console.log(`Hello, my name is ${this.#name}.`);
}
} |
References:
@tbroyer Thanks for starting the discussion on decorator applicability testing. If you have a moment, could I ask for your feedback on the following thoughts?
First of all, if it sounds interesting, you can simply migrate the type test to TSTyche and it will work as expected:
If used without arguments, the
.toRaiseError()
matcher will match any and all semantic errors found in the expression. If substring(s) or error code(s) are provided, only those errors will be matched. To learn more, see documentation: https://tstyche.org/reference/expect-api#to-raise-errorAll works, but the
try..catch
pattern feels somewhat strange. The thing is that TypeScript user does not expect errors while writing code. I mean, we are using TypeScript to get feedback in a form of errors with some guidance how to fix those. As the result, users expect to have working code, but not errors.I have a feeling that testing tools should follow this path. Type tests should demonstrate how APIs can be used, instead of what errors are raised.
Hence
.not.toHaveProperty()
matcher was added recently to TSTyche..not.toBeCallableWith()
and.not.toBeConstructableWith()
are coming soon (see #52). These are complicated. Some progress is done in private branches, not everything is visible in the PR.What if the applicability of a decorator could be tested with a dedicated matcher? On surface it sounds easier to implement than
.toBeCallableWith()
.How this new matcher should it named? Perhaps simply:
.toBeApplicableTo()
. Description: "Checks if the source decorator function can be applied to the target class or class member."The above test becomes:
The text was updated successfully, but these errors were encountered: