-
-
Notifications
You must be signed in to change notification settings - Fork 38
/
testing.ts
108 lines (106 loc) · 3.19 KB
/
testing.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2019-2020 Yusuke Sakurai. All rights reserved. MIT license.
import { BufReader, BufWriter } from "./vendor/https/deno.land/std/io/bufio.ts";
import { Buffer } from "./vendor/https/deno.land/std/io/buffer.ts";
import {
BodyReader,
HttpBody,
IncomingResponse,
ServerRequest,
} from "./server.ts";
import { readResponse, setupBody, writeResponse } from "./serveio.ts";
import { createResponder } from "./responder.ts";
import { closableBodyReader } from "./_readers.ts";
import { parseCookie } from "./cookie.ts";
import {
bodyReader,
chunkedBodyReader,
emptyReader,
} from "./vendor/https/deno.land/std/http/_io.ts";
import { BodyParser, createBodyParser } from "./body_parser.ts";
import { createDataHolder } from "./data_holder.ts";
import { assert } from "./vendor/https/deno.land/std/testing/asserts.ts";
export interface ResponseRecorder extends ServerRequest {
/** Obtain recorded response */
response(): Promise<IncomingResponse & BodyParser>;
}
/** Create dummy request & responder that records a response from HTTPHandler */
export function createRecorder(opts?: {
url?: string;
method?: string;
proto?: string;
headers?: Headers;
body?: HttpBody;
}): ResponseRecorder {
const url = opts?.url ?? "/";
const method = opts?.method ?? "GET";
const headers = opts?.headers ?? new Headers();
const body = opts?.body;
const proto = opts?.proto ?? "http";
const conn: Deno.Conn = {
localAddr: { transport: "tcp", hostname: "0.0.0.0", port: 80 },
remoteAddr: { transport: "tcp", hostname: "0.0.0.0", port: 80 },
rid: 0,
close(): void {},
async closeWrite(): Promise<void> {},
async read(p: Uint8Array): Promise<number | null> {
return 0;
},
async write(p: Uint8Array): Promise<number> {
return 0;
},
};
const buf = new Buffer();
const bufReader = new BufReader(buf);
const bufWriter = new BufWriter(buf);
let br: BodyReader;
if (body) {
const [reader, cl] = setupBody(body, headers);
if (cl !== undefined) {
br = closableBodyReader(bodyReader(cl, new BufReader(reader)));
} else {
br = closableBodyReader(
chunkedBodyReader(headers, new BufReader(reader)),
);
}
} else {
br = closableBodyReader(emptyReader());
}
async function response(): Promise<IncomingResponse & BodyParser> {
const resp = await readResponse(bufReader);
const bodyParser = createBodyParser({
reader: resp.body,
contentType: resp.headers.get("content-type") ?? "",
});
return { ...resp, ...bodyParser };
}
const responder = createResponder(async (resp) => {
return writeResponse(bufWriter, resp);
});
const bodyParser = createBodyParser({
reader: br,
contentType: headers.get("content-type") ?? "",
});
const cookies = parseCookie(headers.get("Cookie") || "");
const { pathname: path, searchParams: query } = new URL(url, "http://dummy");
const dataHolder = createDataHolder();
const match = url.match(/^\//);
assert(match != null);
return {
url,
path,
query,
method,
headers,
proto,
body: br,
response,
bufWriter,
bufReader,
conn,
cookies,
match,
...responder,
...bodyParser,
...dataHolder,
};
}