|
1 | | -<p align="center"> |
2 | | - <a href="https://www.linkedin.com/in/hannah-morten-b1218017a/"><img height="200" style="height: 200px;" src="https://github.com/cmorten/superdeno/raw/main/.github/superdeno.png" alt="Super Deno standing in the rain at night – stoically facing the dark battle that is software engineering"></a> |
3 | | - <h1 align="center">SuperDeno</h1> |
4 | | -</p> |
5 | | -<p align="center"> |
6 | | -HTTP assertions for Deno made easy via <a href="https://github.com/visionmedia/superagent">superagent</a>. |
7 | | -</p> |
8 | | -<p align="center"> |
9 | | - <a href="https://github.com/cmorten/superdeno/tags/"><img src="https://img.shields.io/github/tag/cmorten/superdeno" alt="Current version" /></a> |
10 | | - <img src="https://github.com/cmorten/superdeno/workflows/Test/badge.svg" alt="Current test status" /> |
11 | | - <a href="https://doc.deno.land/https/deno.land/x/superdeno/mod.ts"><img src="https://doc.deno.land/badge.svg" alt="SuperDeno docs" /></a> |
12 | | - <a href="http://makeapullrequest.com"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs are welcome" /></a> |
13 | | - <a href="https://github.com/cmorten/superdeno/issues/"><img src="https://img.shields.io/github/issues/cmorten/superdeno" alt="SuperDeno issues" /></a> |
14 | | - <img src="https://img.shields.io/github/stars/cmorten/superdeno" alt="SuperDeno stars" /> |
15 | | - <img src="https://img.shields.io/github/forks/cmorten/superdeno" alt="SuperDeno forks" /> |
16 | | - <img src="https://img.shields.io/github/license/cmorten/superdeno" alt="SuperDeno license" /> |
17 | | - <a href="https://GitHub.com/cmorten/superdeno/graphs/commit-activity"><img src="https://img.shields.io/badge/Maintained%3F-no-green.svg" alt="SuperDeno is unmaintained" /></a> |
18 | | -</p> |
19 | | -<p align="center"> |
20 | | - <a href="https://deno.land/x/superdeno"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Flatest-version%2Fx%2Fsuperdeno%2Fmod.ts" alt="SuperDeno latest /x/ version" /></a> |
21 | | - <a href="https://github.com/denoland/deno/blob/main/Releases.md"><img src="https://img.shields.io/badge/deno-^1.40.2-brightgreen?logo=deno" alt="Minimum supported Deno version" /></a> |
22 | | - <a href="https://deno-visualizer.danopia.net/dependencies-of/https/deno.land/x/superdeno/mod.ts"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Fdep-count%2Fx%2Fsuperdeno%2Fmod.ts" alt="SuperDeno dependency count" /></a> |
23 | | - <a href="https://deno-visualizer.danopia.net/dependencies-of/https/deno.land/x/superdeno/mod.ts"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Fupdates%2Fx%2Fsuperdeno%2Fmod.ts" alt="SuperDeno dependency outdatedness" /></a> |
24 | | - <a href="https://deno-visualizer.danopia.net/dependencies-of/https/deno.land/x/superdeno/mod.ts"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Fcache-size%2Fx%2Fsuperdeno%2Fmod.ts" alt="SuperDeno cached size" /></a> |
25 | | -</p> |
26 | | - |
27 | | ---- |
28 | | - |
29 | | -_**Now in maintenance mode:** [Deno has introduced Node and NPM compatability](https://docs.deno.com/runtime/fundamentals/node/), consider using [SuperTest](https://www.npmjs.com/package/supertest) itself in |
30 | | -Deno!_ |
31 | | - |
32 | | -```ts |
33 | | -import supertest from "npm:supertest"; |
34 | | -``` |
35 | | - |
36 | | -SuperTest not working for you? [Raise an issue on Deno](https://github.com/denoland/deno/issues) and keep reading for SuperDeno usage :tada: |
37 | | - |
38 | | ---- |
39 | | - |
40 | | -## Table of Contents |
41 | | - |
42 | | -- [Getting Started](#getting-started) |
43 | | -- [About](#about) |
44 | | -- [Installation](#installation) |
45 | | -- [Examples](#examples) |
46 | | -- [Documentation](#documentation) |
47 | | -- [API](#api) |
48 | | -- [Notes](#notes) |
49 | | -- [Contributing](#contributing) |
50 | | -- [License](#license) |
51 | | - |
52 | | -## Getting Started |
53 | | - |
54 | | -```ts |
55 | | -import { superdeno } from "https://deno.land/x/superdeno/mod.ts"; |
56 | | -import { opine } from "https://deno.land/x/[email protected]/mod.ts"; |
57 | | - |
58 | | -const app = opine(); |
59 | | - |
60 | | -app.get("/user", (req, res) => { |
61 | | - res.setStatus(200).json({ name: "Deno" }); |
62 | | -}); |
63 | | - |
64 | | -superdeno(app) |
65 | | - .get("/user") |
66 | | - .expect("Content-Type", /json/) |
67 | | - .expect("Content-Length", "15") |
68 | | - .expect(200) |
69 | | - .end((err, res) => { |
70 | | - if (err) throw err; |
71 | | - }); |
72 | | -``` |
73 | | - |
74 | | -Looking to test an Oak web server? Check out |
75 | | -[SuperOak](https://github.com/cmorten/superoak)! |
76 | | - |
77 | | -## About |
78 | | - |
79 | | -The motivation of this module is to provide a high-level abstraction for testing |
80 | | -HTTP in Deno, while still allowing you to drop down to the lower-level API |
81 | | -provided by [superagent](https://visionmedia.github.io/superagent/). |
82 | | - |
83 | | -## Installation |
84 | | - |
85 | | -This is a [Deno](https://deno.land/) module available to import direct from this |
86 | | -repo and via the [Deno Registry](https://deno.land/x). |
87 | | - |
88 | | -Before importing, [download and install Deno](https://deno.land/#installation). |
89 | | - |
90 | | -You can then import SuperDeno straight into your project: |
91 | | - |
92 | | -```ts |
93 | | -import { superdeno } from "https://deno.land/x/superdeno/mod.ts"; |
94 | | -``` |
95 | | - |
96 | | -SuperDeno is also available on [nest.land](https://nest.land/package/superdeno), |
97 | | -a package registry for Deno on the Blockchain. |
98 | | - |
99 | | -> Note: All examples in this README are using the unversioned form of the import URL. In production you should always use the versioned import form such as `https://deno.land/x/[email protected]/mod.ts`. |
100 | | -
|
101 | | -## Examples |
102 | | - |
103 | | -You may pass a url string, |
104 | | -[`http.Server`](https://doc.deno.land/https/deno.land/std/http/mod.ts#Server), a |
105 | | -request handling function, or an object that implements an `app.listen()` method |
106 | | -(which mirrors the |
107 | | -[`http.serve`](https://doc.deno.land/https/deno.land/std/http/mod.ts#serve) |
108 | | -interface) to `superdeno()` - if SuperDeno identifies that a server is not |
109 | | -already listening for connections, then one is bound to an ephemeral port for |
110 | | -you so there is no need to keep track of ports. |
111 | | - |
112 | | -SuperDeno works with any Deno test framework. Here's an example with Deno's |
113 | | -built-in test framework, note how you can pass `done` straight to any of the |
114 | | -`.expect()` calls: |
115 | | - |
116 | | -```ts |
117 | | -Deno.test("GET /user responds with json", async () => { |
118 | | - await superdeno(app) |
119 | | - .get("/user") |
120 | | - .set("Accept", "application/json") |
121 | | - .expect("Content-Type", /json/) |
122 | | - .expect(200); |
123 | | -}); |
124 | | -``` |
125 | | - |
126 | | -Here's an example of SuperDeno working with the Opine web framework: |
127 | | - |
128 | | -```ts |
129 | | -import { superdeno } from "https://deno.land/x/superdeno/mod.ts"; |
130 | | -import { opine } from "https://deno.land/x/[email protected]/mod.ts"; |
131 | | -import { expect } from "https://deno.land/x/[email protected]/mod.ts"; |
132 | | - |
133 | | -const app = opine(); |
134 | | - |
135 | | -app.get("/", (req, res) => { |
136 | | - res.send("Hello Deno!"); |
137 | | -}); |
138 | | - |
139 | | -Deno.test("it should support regular expressions", async () => { |
140 | | - await superdeno(app) |
141 | | - .get("/") |
142 | | - .expect("Content-Type", /^application/) |
143 | | - .catch((err) => { |
144 | | - expect(err.message).toEqual( |
145 | | - 'expected "Content-Type" matching /^application/, got "text/html; charset=utf-8"' |
146 | | - ); |
147 | | - }); |
148 | | -}); |
149 | | -``` |
150 | | - |
151 | | -See more examples in the [Opine test suite](./test/superdeno.opine.test.ts). |
152 | | - |
153 | | -Here's an example of SuperDeno working with the Express web framework: |
154 | | - |
155 | | -```ts |
156 | | -import { superdeno } from "https://deno.land/x/superdeno/mod.ts"; |
157 | | -// @deno-types="npm:@types/express@^4.17" |
158 | | -import express from "npm:[email protected]"; |
159 | | -import { expect } from "https://deno.land/x/[email protected]/mod.ts"; |
160 | | - |
161 | | -Deno.test("it should support regular expressions", async () => { |
162 | | - const app = express(); |
163 | | - |
164 | | - app.get("/", (_req, res) => { |
165 | | - res.send("Hello Deno!"); |
166 | | - }); |
167 | | - |
168 | | - await superdeno(app) |
169 | | - .get("/") |
170 | | - .expect("Content-Type", /^application/) |
171 | | - .catch((err) => { |
172 | | - expect(err.message).toEqual( |
173 | | - 'expected "Content-Type" matching /^application/, got "text/html; charset=utf-8"' |
174 | | - ); |
175 | | - }); |
176 | | -}); |
177 | | -``` |
178 | | - |
179 | | -See more examples in the [Express test suite](./test/superdeno.express.test.ts). |
180 | | - |
181 | | -Here's an example of SuperDeno working with the Oak web framework: |
182 | | - |
183 | | -```ts |
184 | | -import { superdeno } from "https://deno.land/x/superdeno/mod.ts"; |
185 | | -import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts"; |
186 | | - |
187 | | -const router = new Router(); |
188 | | -router.get("/", (ctx) => { |
189 | | - ctx.response.body = "Hello Deno!"; |
190 | | -}); |
191 | | - |
192 | | -const app = new Application(); |
193 | | -app.use(router.routes()); |
194 | | -app.use(router.allowedMethods()); |
195 | | - |
196 | | -Deno.test("it should support the Oak framework", () => { |
197 | | - const controller = new AbortController(); |
198 | | - const { signal } = controller; |
199 | | - |
200 | | - app.addEventListener("listen", async ({ hostname, port, secure }) => { |
201 | | - const protocol = secure ? "https" : "http"; |
202 | | - const url = `${protocol}://${hostname}:${port}`; |
203 | | - |
204 | | - await superdeno(url) |
205 | | - .get("/") |
206 | | - .expect("Hello Deno!", () => { |
207 | | - controller.abort(); |
208 | | - }); |
209 | | - }); |
210 | | - |
211 | | - await app.listen({ port: 0, signal }); |
212 | | -}); |
213 | | -``` |
214 | | - |
215 | | -See more examples in the [Oak test suite](./test/superdeno.oak.test.ts). |
216 | | - |
217 | | -If you are using the [Oak](https://github.com/oakserver/oak/) web framework then |
218 | | -it is recommended that you use the specialized |
219 | | -[SuperOak](https://github.com/cmorten/superoak) assertions library for |
220 | | -reduced bootstrapping. |
221 | | - |
222 | | -If you don't need to test the server setup side of your Oak application, or you |
223 | | -are making use of the `app.handle()` method (for example for serverless apps) |
224 | | -then you can write slightly less verbose tests for Oak: |
225 | | - |
226 | | -```ts |
227 | | -import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts"; |
228 | | -import { superdeno } from "https://deno.land/x/superdeno/mod.ts"; |
229 | | - |
230 | | -const router = new Router(); |
231 | | - |
232 | | -router.get("/", (ctx) => { |
233 | | - ctx.response.body = "Hello Deno!"; |
234 | | -}); |
235 | | - |
236 | | -const app = new Application(); |
237 | | -app.use(router.routes()); |
238 | | -app.use(router.allowedMethods()); |
239 | | - |
240 | | -Deno.test( |
241 | | - "it should support the Oak framework `app.handle` method", |
242 | | - async () => { |
243 | | - /** |
244 | | - * Note that we have to bind `app` to the function otherwise `app.handle` |
245 | | - * doesn't preserve the `this` context from `app`. |
246 | | - */ |
247 | | - await superdeno(app.handle.bind(app)).get("/").expect("Hello Deno!"); |
248 | | - } |
249 | | -); |
250 | | -``` |
251 | | - |
252 | | -In this case, SuperDeno handles the setup and closing of the server for you, so |
253 | | -you can focus on just testing your middleware. |
254 | | - |
255 | | -For further examples, see the [tests](./test) or the |
256 | | -[supertest examples](https://github.com/visionmedia/supertest#example) for |
257 | | -inspiration. |
258 | | - |
259 | | -## Documentation |
260 | | - |
261 | | -- [SuperDeno Deno Docs](https://doc.deno.land/https/deno.land/x/superdeno/mod.ts) |
262 | | -- [SuperDeno Type Docs](https://cmorten.github.io/superdeno/) |
263 | | -- [License](https://github.com/cmorten/superdeno/blob/main/LICENSE.md) |
264 | | -- [Changelog](https://github.com/cmorten/superdeno/blob/main/.github/CHANGELOG.md) |
265 | | - |
266 | | -## API |
267 | | - |
268 | | -You may use any [superagent](http://github.com/visionmedia/superagent) client |
269 | | -(browser) methods and perform assertions in the `.end()` callback for |
270 | | -lower-level needs. |
271 | | - |
272 | | -### .expect(status[, fn]) |
273 | | - |
274 | | -Assert response `status` code. |
275 | | - |
276 | | -### .expect(status, body[, fn]) |
277 | | - |
278 | | -Assert response `status` code and `body`. |
279 | | - |
280 | | -### .expect(body[, fn]) |
281 | | - |
282 | | -Assert response `body` text with a string, regular expression, or parsed body |
283 | | -object. |
284 | | - |
285 | | -### .expect(field, value[, fn]) |
286 | | - |
287 | | -Assert header `field` `value` with a string or regular expression. |
288 | | - |
289 | | -### .expect(function(res) {}) |
290 | | - |
291 | | -Pass a custom assertion function. It'll be given the response object to check. |
292 | | -If the check fails, throw an error. |
293 | | - |
294 | | -```ts |
295 | | -function hasPreviousAndNextKeys(res) { |
296 | | - if (!("next" in res.parsedBody)) throw new Error("missing next key"); |
297 | | - if (!("prev" in res.parsedBody)) throw new Error("missing prev key"); |
298 | | -} |
299 | | - |
300 | | -await superdeno(app).get("/").expect(hasPreviousAndNextKeys); |
301 | | -``` |
302 | | - |
303 | | -### .end(fn) |
304 | | - |
305 | | -Perform the request and invoke `fn(err, res)`. |
306 | | - |
307 | | -## Notes |
308 | | - |
309 | | -This is a port of [supertest](https://github.com/visionmedia/supertest) to |
310 | | -TypeScript + Deno, which fulfills this motivation currently for Node. This |
311 | | -module also includes a XHR sham so |
312 | | -[superagent](https://visionmedia.github.io/superagent/) client mode can be used |
313 | | -directly. |
314 | | - |
315 | | -## Contributing |
316 | | - |
317 | | -[Contributing guide](https://github.com/cmorten/superdeno/blob/main/.github/CONTRIBUTING.md) |
318 | | - |
319 | | ---- |
320 | | - |
321 | | -## License |
322 | | - |
323 | | -This library is a port of [supertest](https://github.com/visionmedia/supertest) |
324 | | -whose license and copyrights are available at |
325 | | -[SUPERTEST_LICENSE](./SUPERTEST_LICENSE.md) in the root of this repository, and |
326 | | -covers all files within the [source](./src) directory which detail that the file |
327 | | -is a port. |
328 | | - |
329 | | -SuperDeno is licensed under the [MIT License](./LICENSE.md). |
330 | | - |
331 | | -Icon designed and created by |
332 | | -[Hannah Morten](https://www.linkedin.com/in/hannah-morten-b1218017a/). |
| 1 | +This is a fork of [superdeno](https://github.com/cmorten/superdeno#api) with the changes necessary for Deno 2.0 based off of https://github.com/cmorten/superdeno/pull/45. However that PR has been in limbo for a while due to being unable to properly run tests due to further dependencies not supporting Deno 2. So while this fork should support Deno 2 there is no guarantee that everything works due to not having the tests. |
0 commit comments