Skip to content

Commit 541fcfc

Browse files
committed
feat(fetch): make it easier to generate typed clients for testing
1 parent 0f1e6ac commit 541fcfc

File tree

3 files changed

+586
-835
lines changed

3 files changed

+586
-835
lines changed

package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,35 +52,35 @@
5252
"devDependencies": {
5353
"@commitlint/cli": "^17.7.1",
5454
"@commitlint/config-conventional": "^17.7.0",
55-
"@openapi-typescript-infra/coconfig": "^4.0.2",
56-
"@openapi-typescript-infra/service": "^2.0.1",
55+
"@openapi-typescript-infra/coconfig": "^4.1.0",
56+
"@openapi-typescript-infra/service": "^2.6.3",
5757
"@semantic-release/changelog": "^6.0.3",
58-
"@semantic-release/commit-analyzer": "^10.0.1",
58+
"@semantic-release/commit-analyzer": "^10.0.4",
5959
"@semantic-release/exec": "^6.0.3",
6060
"@semantic-release/git": "^10.0.1",
61-
"@semantic-release/release-notes-generator": "^11.0.4",
62-
"@types/lodash": "^4.14.197",
63-
"@typescript-eslint/eslint-plugin": "^6.4.0",
64-
"@typescript-eslint/parser": "^6.4.0",
65-
"@vitest/coverage-v8": "^0.34.2",
61+
"@semantic-release/release-notes-generator": "^11.0.7",
62+
"@types/lodash": "^4.14.198",
63+
"@typescript-eslint/eslint-plugin": "^6.7.0",
64+
"@typescript-eslint/parser": "^6.7.0",
65+
"@vitest/coverage-v8": "^0.34.4",
6666
"coconfig": "^0.13.3",
6767
"eslint-config-prettier": "^9.0.0",
68-
"eslint-plugin-import": "^2.28.0",
69-
"eslint-plugin-jest": "^27.2.3",
68+
"eslint-plugin-import": "^2.28.1",
7069
"ts-node": "^10.9.1",
71-
"vitest": "^0.34.2"
70+
"vitest": "^0.34.4"
7271
},
7372
"dependencies": {
7473
"@types/supertest": "^2.0.12",
75-
"eslint": "^8.47.0",
74+
"eslint": "^8.49.0",
7675
"find-up": "^6.3.0",
7776
"lodash": "^4.17.21",
7877
"pino-pretty": "^10.2.0",
7978
"read-pkg-up": "^7.0.1",
8079
"rest-api-support": "^1.16.3",
8180
"supertest": "^6.3.3",
81+
"supertest-fetch": "^1.5.0",
8282
"tsconfig-paths": "^4.2.0",
83-
"typescript": "^5.1.6"
83+
"typescript": "^5.2.2"
8484
},
8585
"packageManager": "[email protected]"
8686
}

src/index.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import path from 'path';
22
import assert from 'assert';
33

4+
import request from 'supertest';
5+
import { makeFetch } from 'supertest-fetch';
46
// We are going to test Typescript files, so use the ts-node
57
// register hook to allow require to resolve these modules
68
import { register } from 'ts-node';
@@ -99,6 +101,22 @@ export function getExistingApp<SLocals extends ServiceLocals = ServiceLocals>()
99101
return app as ServiceExpress<SLocals>;
100102
}
101103

104+
class RequestTestingHelpers {
105+
_fetch: ReturnType<typeof makeFetch>;
106+
107+
constructor(private app: ServiceExpress) {
108+
this._fetch = makeFetch(app as unknown as Parameters<typeof makeFetch>[0]);
109+
}
110+
111+
get request() {
112+
return request(this.app);
113+
}
114+
115+
get fetch() {
116+
return this._fetch as unknown as typeof fetch;
117+
}
118+
}
119+
102120
export async function getReusableApp<
103121
SLocals extends ServiceLocals = ServiceLocals,
104122
RLocals extends RequestLocals = RequestLocals,
@@ -107,21 +125,23 @@ export async function getReusableApp<
107125
| Partial<ServiceStartOptions<SLocals, RLocals>>
108126
| ServiceFactory<SLocals, RLocals>,
109127
cwd?: string,
110-
): Promise<ServiceExpress<SLocals>> {
128+
): Promise<ServiceExpress<SLocals> & { test: RequestTestingHelpers }> {
111129
const logFn = (error: Error) => {
112130
// eslint-disable-next-line no-console
113131
console.error('Could not start app', error);
114132
throw error;
115133
};
116-
let typedApp = app as ServiceExpress<SLocals>;
134+
let typedApp = app as ServiceExpress<SLocals> & { test: RequestTestingHelpers };
117135

118136
try {
119137
const options = await readOptions(cwd || process.cwd(), initialOptions).catch(logFn);
120138
if (!app || appService !== options.service) {
121-
typedApp = await startApp(options).catch(logFn);
139+
const untypedApp = await startApp(options).catch(logFn);
140+
typedApp = Object.assign(untypedApp, {
141+
test: new RequestTestingHelpers(untypedApp),
142+
});
122143
appService = options.service as ServiceFactory<ServiceLocals, RequestLocals>;
123144
app = typedApp;
124-
return typedApp;
125145
}
126146
return typedApp;
127147
} catch (error) {

0 commit comments

Comments
 (0)