-
Notifications
You must be signed in to change notification settings - Fork 638
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
Less verbose test function #93
Comments
Personally, I really hate overloads that change the ariaty of the arguments. Omitting "optional" parameters is different. Adding complexity to a straight forward API without real value doesn't seem warranted IMO. |
Well, yeah, that would change the arity of the function. Before, however, the arity was kind of "hidden" in the object properties. In both cases, two things (the name and a function) need to be passed to the test function. I still think an options object with two specifically named properties is more complex than two parameters... But it might also be that it's just more familiar to me since quite a lot of JS testing frameworks (for example, |
See also denoland/deno#20 |
I think It is good idea.
I agree. I rarely saw test runner written in that style, As @kitsonk said, I know defining typed function with different number of arguments is quite complicated. But It can be by TypeScript. I understand this may not be the best, but believe a great and flexible feature of TS(JS). Patches will be like this: export type TestDescription = {
(description: string, body: TestFunction)
(body: TestFunction)
}
export const test: TestDescription = function test (descOrBody: string|TestFunction, body?: TestFunction): void {
let name: string;
let fn: TestFunction;
if (typeof descOrBody === "string") {
name = descOrBody;
fn = body;
} else {
name = descOrBody.name;
fn = descOrBody;
}
if (!name) {
throw new Error("Test function may not be anonymous");
}
if (filter(name)) {
tests.push({ fn, name });
} else {
filtered++;
}
} Obviously, more discussions will be needed🧐 |
I think the correct overloaded typings are: declare function test(fn: () => void): void;
declare function test(name: string, fn: () => void): void; Which could be used as follows: test(function example() { /* test code */ })
test('example', () => { /* test code */ }) Unfortunately, I don't think it's possible to distinguish named and anonymous functions in TypeScript... so that's gotta be a runtime |
The implementation of the overloading might not look all too pretty. export function test(fnOrName: (() => void) | string, undefOrFn?: () => void) {
if (typeof fnOrName === "function") {
if (fnOrName.name === "") {
throw new Error(`'fn' must be a named function`);
} else if (undefOrFn !== undefined) {
throw new Error(`second parameter must be 'undefined'`);
} else {
let fn = fnOrName;
let name = fnOrName.name;
// Yay!
}
} else if (typeof fnOrName === "string") {
if (typeof undefOrFn !== "function") {
throw new Error(
`'fn' must be typeof 'function', but found '${typeof fnOrNone}'`
);
} else {
let fn = undefOrFn;
let name = fnOrName;
// Yay!
}
} else {
throw new Error(
`first parameter must be typeof 'function' or 'string', but found '${typeof fnOrName}'`
);
}
} But using the API is more intuitive, IMHO. |
@ry Would you accept a PR that implements this breaking change? If so, I'd start working on it. |
@MarkTiedemann Seems reasonable to me. Go for it. |
I dislike overloading this much further... I think it's going to be much more useful to add setup and teardown, an example might be something like this: hayd@987ef51 |
@MarkTiedemann Any progress? I want see it 🧐. |
Not yet, unfortunately. I was working on My next week is gonna be busy, too, so if you want to work on it, feel free!
I guess that's a matter of taste. I personally don't like it when test frameworks offer a special way to do setup and teardown (which you have to learn or look up in the docs). I prefer a plain old function call for setup and a try-finally-block with a function call for teardown. For example: test(function exampleTest() {
mySetupCode()
try {
myTestCode()
} finally {
myTeardownCode()
}
}) In this case, you don't have to know the test framework. This works everywhere JS works. It's plain and simple. Also, not many test cases actually require custom setup or teardown code, whereas all test cases require a name. So if I had to choose between those features, as you seem to imply, I'd go with the less verbose naming feature rather than the setup and teardown feature. |
See also #128. |
What do y'all think about AVA's API? Personally I love it and it already has great TS types, so should be very easy for Deno to adopt. |
If someone ported AVA to deno_std and it worked perfectly, I would be happy to have it. But likely that won't happen - because it looks big and complex. I'm a fan of the current testing module because of how minimal it is. I realize it has some problems at the moment (#152, #162, #122), but I intend to clean it up soon. I think it's worthwhile to have a very minimal std testing module. |
Sorry, I meant the API definition (or a small subset of it), not necessarily the implementation. Would be awesome if AVA's implementation could be ported, but I agree that sounds hard. Among other things, AVA relies on Node's If, however, Deno were to adopt the API of a popular framework like AVA, it would make it easier to port the implementation in the future as better tooling comes along to do that, and as libraries begin to use more runtime agnostic patterns. At the very least it would make Deno more familiar and approachable. The similarities don't have to go super deep, IMO, as long as test definitions and assertions are the same. |
@sholladay Hm - looks quite minimal and similar to ours. I'm not opposed to that API. @piscisaureus thoughts? https://github.com/avajs/ava/blob/master/docs/01-writing-tests.md |
Currently, the
test
function has the following usage:I like
#2
, but I think#1
is a bit verbose.How about this instead?
The text was updated successfully, but these errors were encountered: