1- import { assertEquals , assertMatch , getFreePort } from './deps.ts'
2- import { HandlerOrListener } from './types.ts'
1+ import { assertEquals , assertMatch } from './deps.ts'
2+ import { Handler , HandlerOrListener } from './types.ts'
33
4- const port = await getFreePort ( 8080 )
4+ // credit - 'https://deno.land/x/free_port@v1.2.0/mod.ts'
5+ function random ( min : number , max : number ) : number {
6+ return Math . round ( Math . random ( ) * ( max - min ) ) + min
7+ }
8+
9+ // credit - 'https://deno.land/x/free_port@v1.2.0/mod.ts'
10+ const getFreeListener = (
11+ port : number ,
12+ ) : { listener : Deno . Listener ; port : number } => {
13+ try {
14+ const listener = Deno . listen ( { port : port } )
15+ return { listener, port }
16+ } catch ( error ) {
17+ if ( error instanceof Deno . errors . AddrInUse ) {
18+ const newPort = random ( 1024 , 49151 )
19+ return getFreeListener ( newPort )
20+ }
21+ }
22+ throw Error
23+ }
524
625const fetchEndpoint = async (
726 port : number ,
@@ -20,10 +39,12 @@ const fetchEndpoint = async (
2039 else data = await res . arrayBuffer ( )
2140 return { res, data }
2241}
23-
2442const makeFetchPromise = ( handlerOrListener : HandlerOrListener ) => {
25- // listener
26- if ( 'rid' in handlerOrListener && 'addr' in handlerOrListener ) {
43+ if ( 'rid' in handlerOrListener && 'adr' in handlerOrListener ) {
44+ // this might never get invoked because of Deno's blocking issue
45+ const port = ( handlerOrListener . addr as Deno . NetAddr ) . port ;
46+ if ( ! port )
47+ throw new Error ( "Port cannot be found" ) ;
2748 return async ( url : URL | string = '' , params ?: RequestInit ) => {
2849 const p = new Promise < { res : Response ; data ?: unknown } > ( ( resolve ) => {
2950 setTimeout ( async ( ) => {
@@ -36,31 +57,30 @@ const makeFetchPromise = (handlerOrListener: HandlerOrListener) => {
3657 const conn = await handlerOrListener . accept ( )
3758 return p
3859 }
39- } // (req, conn) => Response listener
40- else {
41- const listener = Deno . listen ( { port, hostname : 'localhost' } )
42-
60+ } else {
61+ const { listener, port } = getFreeListener ( random ( 1024 , 49151 ) )
4362 const serve = async ( conn : Deno . Conn ) => {
4463 const requests = Deno . serveHttp ( conn )
4564 const { request, respondWith } = ( await requests . nextRequest ( ) ) !
46- const response = await handlerOrListener ( request , conn )
65+
66+ const response = await ( handlerOrListener as Handler ) ( request , conn )
4767 if ( response ) {
4868 respondWith ( response )
4969 }
5070 }
5171
5272 return async ( url : URL | string = '' , params ?: RequestInit ) => {
53- const p = new Promise < { res : Response ; data ?: unknown } > ( ( resolve ) => {
54- setTimeout ( async ( ) => {
55- const { res , data } = await fetchEndpoint ( port , url , params )
56- resolve ( { res , data } )
57- Deno . close ( conn . rid + 1 )
58- listener . close ( )
59- } )
60- } )
61- const conn = await listener . accept ( )
62- await serve ( conn )
63- return p
73+ const connector = async ( ) => {
74+ const conn = await listener . accept ( )
75+ await serve ( conn )
76+ return conn
77+ }
78+ const connection = connector ( )
79+ const res = await fetchEndpoint ( port , url , params )
80+ await connection . then ( ( con ) => Deno . close ( con . rid + 1 ) ) . finally ( ( ) =>
81+ listener . close ( )
82+ )
83+ return res
6484 }
6585 }
6686}
@@ -69,6 +89,7 @@ export const makeFetch = (h: HandlerOrListener) => {
6989 const resp = makeFetchPromise ( h )
7090 async function fetch ( url : string | URL , options ?: RequestInit ) {
7191 const { data, res } = await resp ( url , options )
92+
7293 const expectStatus = ( a : number , b ?: string ) => {
7394 assertEquals (
7495 res . status ,
@@ -82,7 +103,7 @@ export const makeFetch = (h: HandlerOrListener) => {
82103 expect : expectAll ,
83104 expectStatus,
84105 expectHeader,
85- expectBody,
106+ expectBody
86107 }
87108 }
88109 const expectHeader = ( a : string , b : string | RegExp | null | string [ ] ) => {
@@ -121,7 +142,7 @@ export const makeFetch = (h: HandlerOrListener) => {
121142 expect : expectAll ,
122143 expectStatus,
123144 expectHeader,
124- expectBody,
145+ expectBody
125146 }
126147 }
127148 const expectBody = ( a : unknown ) => {
@@ -143,12 +164,12 @@ export const makeFetch = (h: HandlerOrListener) => {
143164 expectBody,
144165 }
145166 }
146-
147167 return {
148168 expect : expectAll ,
149169 expectStatus,
150170 expectHeader,
151171 expectBody,
172+ ...res
152173 }
153174 }
154175 return fetch
0 commit comments