Skip to content

Commit

Permalink
fix: infer typing in promise fn argument
Browse files Browse the repository at this point in the history
  • Loading branch information
wdavidw committed Sep 28, 2024
1 parent b09932f commit 698f48b
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 16 deletions.
2 changes: 1 addition & 1 deletion samples/before-after-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const they = configure<Config, ConfigConnected>(
);

describe("Test before/after usage", function () {
they("Called 3 times", function (config: ConfigConnected) {
they("Called 3 times", function (config) {
if (config.ssh === undefined) {
console.info(" ".repeat(6) + "SSH client not connected");
} else {
Expand Down
2 changes: 1 addition & 1 deletion samples/usage-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const they = configure<Config>([
]);

describe("Test mocha-they", function () {
they("Call 2 times", function (conf: Config) {
they("Call 2 times", function (conf) {
if (conf.ssh === undefined) {
console.info(" ".repeat(6) + "Got null.");
} else {
Expand Down
23 changes: 13 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,11 @@ export type TheyFunc<T> = (
config: T,
done: mocha.Done,
) => void;
export type TheyAsyncFunc<T> = (
this: mocha.Context,
config: T,
) => PromiseLike<unknown>;

type They<T> = {
only: (msg: string, fn: TheyFunc<T> | TheyAsyncFunc<T>) => mocha.Test[];
skip: (msg: string, fn: TheyFunc<T> | TheyAsyncFunc<T>) => mocha.Test[];
(msg: string, fn: TheyFunc<T> | TheyAsyncFunc<T>): mocha.Test[];
only: (msg: string, fn: TheyFunc<T>) => mocha.Test[];
skip: (msg: string, fn: TheyFunc<T>) => mocha.Test[];
(msg: string, fn: TheyFunc<T>): mocha.Test[];
};

function configure<T>(configs: (T | (() => T))[]): They<T>;
Expand Down Expand Up @@ -59,7 +55,7 @@ function configure<T, U = T>(
function handle(
msg: string,
label: string,
fn: TheyFunc<U> | TheyAsyncFunc<U>,
fn: TheyFunc<U>,
config: T | (() => T),
): [string, mocha.Func | mocha.AsyncFunc] {
if (typeof config === "function") {
Expand All @@ -71,26 +67,29 @@ function configure<T, U = T>(
`${msg} (${label})`,
fn.length === 0 || fn.length === 1 ?
(function (this: mocha.Context) {
// return (fn as TheyAsyncFunc<T | U>).call(this, configNormalized);
// Promise Style
return Promise.resolve()
.then(async () => {
// Before hook
const configNormalized =
// eslint-disable-next-line mocha/no-top-level-hooks
before === undefined ? config : await before(config);
return configNormalized;
})
.then(async (config): Promise<[T | U, unknown, unknown]> => {
// Handler execution
try {
return [
config,
undefined,
await (fn as TheyAsyncFunc<T | U>).call(this, config),
await (fn as TheyFunc<T | U>).call(this, config, () => {}),
];
} catch (err: unknown) {
return [config, err, undefined];
}
})
.then(async ([config, err, prom]) => {
// After hook
if (after !== undefined) {
// eslint-disable-next-line mocha/no-top-level-hooks
await after(config);
Expand All @@ -103,15 +102,18 @@ function configure<T, U = T>(
});
} as mocha.AsyncFunc)
: (function (this: mocha.Context, next: mocha.Done) {
// Callback Style
Promise.resolve()
.then(async () => {
// Before hook
const configNormalized =
// eslint-disable-next-line mocha/no-sibling-hooks,mocha/no-top-level-hooks
before === undefined ? config : await before(config);
return configNormalized;
})
.then(
(config) =>
// Handler execution
new Promise<[T | U, unknown[]]>((resolve) => {
(fn as TheyFunc<T | U>).call(
this,
Expand All @@ -123,6 +125,7 @@ function configure<T, U = T>(
}),
)
.then(async ([config, args]: [T | U, unknown[]]) => {
// After hook
if (after === undefined) return next(...args);
// eslint-disable-next-line mocha/no-sibling-hooks,mocha/no-top-level-hooks
await after(config);
Expand Down
23 changes: 20 additions & 3 deletions test/handler.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import should from "should";
import { configure } from "../src/index.js";

interface Config {
ssh: {
ssh: null | {
host: string;
username: string | undefined;
};
}

const they = configure<null | Config>([
null,
const they = configure<Config>([
{ ssh: null },
{ ssh: { host: "127.0.0.1", username: process.env.USER } },
]);

describe("they.handler", function () {
describe("promise", function () {
they("argument is typed", function ({ ssh }) {
// Test this
this.retries(1);
// Test function argument
should(ssh === null || typeof ssh.host === "string").be.true();
return true;
});

they("return `true`", function () {
return true;
});
Expand All @@ -30,6 +39,14 @@ describe("they.handler", function () {
});

describe("callbak", function () {
they("argument is typed", function ({ ssh }, next) {
// Test this
this.retries(1);
// Test function argument
should(ssh === null || typeof ssh.host === "string").be.true();
next();
});

they("call next synchronously", function (conf, next) {
this.timeout(200);
next();
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
/* Enable all strict type-checking options. */
"strict": true,
"sourceMap": true,
"declaration": true
"declaration": true,
"allowSyntheticDefaultImports": true
}
}

0 comments on commit 698f48b

Please sign in to comment.