Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cmorten/superdeno
Super-agent driven library for testing Deno HTTP servers.
https://github.com/cmorten/superdeno
assertions deno deno-doc http-testing oak opine superagent superdeno supertest testing typescript
Last synced: 7 days ago
JSON representation
Super-agent driven library for testing Deno HTTP servers.
- Host: GitHub
- URL: https://github.com/cmorten/superdeno
- Owner: cmorten
- License: mit
- Created: 2020-05-29T08:00:22.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-01-28T13:17:45.000Z (9 months ago)
- Last Synced: 2024-10-01T08:33:02.588Z (about 1 month ago)
- Topics: assertions, deno, deno-doc, http-testing, oak, opine, superagent, superdeno, supertest, testing, typescript
- Language: TypeScript
- Homepage: https://cmorten.github.io/superdeno/
- Size: 1.35 MB
- Stars: 122
- Watchers: 3
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: .github/CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS.md
- Security: SECURITY.md
Awesome Lists containing this project
- awesome-deno-cn - @asos-craigmorten/superdeno
README
SuperDeno
HTTP assertions for Deno made easy via superagent.
---
_**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
Deno!_```ts
import supertest from "npm:supertest";
```SuperTest not working for you? [Raise an issue on Deno](https://github.com/denoland/deno/issues) and keep reading for SuperDeno usage :tada:
---
## Table of Contents
- [Getting Started](#getting-started)
- [About](#about)
- [Installation](#installation)
- [Examples](#examples)
- [Documentation](#documentation)
- [API](#api)
- [Notes](#notes)
- [Contributing](#contributing)
- [License](#license)## Getting Started
```ts
import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
import { opine } from "https://deno.land/x/[email protected]/mod.ts";const app = opine();
app.get("/user", (req, res) => {
res.setStatus(200).json({ name: "Deno" });
});superdeno(app)
.get("/user")
.expect("Content-Type", /json/)
.expect("Content-Length", "15")
.expect(200)
.end((err, res) => {
if (err) throw err;
});
```Looking to test an Oak web server? Check out
[SuperOak](https://github.com/cmorten/superoak)!## About
The motivation of this module is to provide a high-level abstraction for testing
HTTP in Deno, while still allowing you to drop down to the lower-level API
provided by [superagent](https://visionmedia.github.io/superagent/).## Installation
This is a [Deno](https://deno.land/) module available to import direct from this
repo and via the [Deno Registry](https://deno.land/x).Before importing, [download and install Deno](https://deno.land/#installation).
You can then import SuperDeno straight into your project:
```ts
import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
```SuperDeno is also available on [nest.land](https://nest.land/package/superdeno),
a package registry for Deno on the Blockchain.> 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`.
## Examples
You may pass a url string,
[`http.Server`](https://doc.deno.land/https/deno.land/std/http/mod.ts#Server), a
request handling function, or an object that implements an `app.listen()` method
(which mirrors the
[`http.serve`](https://doc.deno.land/https/deno.land/std/http/mod.ts#serve)
interface) to `superdeno()` - if SuperDeno identifies that a server is not
already listening for connections, then one is bound to an ephemeral port for
you so there is no need to keep track of ports.SuperDeno works with any Deno test framework. Here's an example with Deno's
built-in test framework, note how you can pass `done` straight to any of the
`.expect()` calls:```ts
Deno.test("GET /user responds with json", async () => {
await superdeno(app)
.get("/user")
.set("Accept", "application/json")
.expect("Content-Type", /json/)
.expect(200);
});
```Here's an example of SuperDeno working with the Opine web framework:
```ts
import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
import { opine } from "https://deno.land/x/[email protected]/mod.ts";
import { expect } from "https://deno.land/x/[email protected]/mod.ts";const app = opine();
app.get("/", (req, res) => {
res.send("Hello Deno!");
});Deno.test("it should support regular expressions", async () => {
await superdeno(app)
.get("/")
.expect("Content-Type", /^application/)
.catch((err) => {
expect(err.message).toEqual(
'expected "Content-Type" matching /^application/, got "text/html; charset=utf-8"'
);
});
});
```See more examples in the [Opine test suite](./test/superdeno.opine.test.ts).
Here's an example of SuperDeno working with the Express web framework:
```ts
import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
// @deno-types="npm:@types/express@^4.17"
import express from "npm:[email protected]";
import { expect } from "https://deno.land/x/[email protected]/mod.ts";Deno.test("it should support regular expressions", async () => {
const app = express();app.get("/", (_req, res) => {
res.send("Hello Deno!");
});await superdeno(app)
.get("/")
.expect("Content-Type", /^application/)
.catch((err) => {
expect(err.message).toEqual(
'expected "Content-Type" matching /^application/, got "text/html; charset=utf-8"'
);
});
});
```See more examples in the [Express test suite](./test/superdeno.express.test.ts).
Here's an example of SuperDeno working with the Oak web framework:
```ts
import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts";const router = new Router();
router.get("/", (ctx) => {
ctx.response.body = "Hello Deno!";
});const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());Deno.test("it should support the Oak framework", () => {
const controller = new AbortController();
const { signal } = controller;app.addEventListener("listen", async ({ hostname, port, secure }) => {
const protocol = secure ? "https" : "http";
const url = `${protocol}://${hostname}:${port}`;await superdeno(url)
.get("/")
.expect("Hello Deno!", () => {
controller.abort();
});
});await app.listen({ port: 0, signal });
});
```See more examples in the [Oak test suite](./test/superdeno.oak.test.ts).
If you are using the [Oak](https://github.com/oakserver/oak/) web framework then
it is recommended that you use the specialized
[SuperOak](https://github.com/cmorten/superoak) assertions library for
reduced bootstrapping.If you don't need to test the server setup side of your Oak application, or you
are making use of the `app.handle()` method (for example for serverless apps)
then you can write slightly less verbose tests for Oak:```ts
import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts";
import { superdeno } from "https://deno.land/x/superdeno/mod.ts";const router = new Router();
router.get("/", (ctx) => {
ctx.response.body = "Hello Deno!";
});const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());Deno.test(
"it should support the Oak framework `app.handle` method",
async () => {
/**
* Note that we have to bind `app` to the function otherwise `app.handle`
* doesn't preserve the `this` context from `app`.
*/
await superdeno(app.handle.bind(app)).get("/").expect("Hello Deno!");
}
);
```In this case, SuperDeno handles the setup and closing of the server for you, so
you can focus on just testing your middleware.For further examples, see the [tests](./test) or the
[supertest examples](https://github.com/visionmedia/supertest#example) for
inspiration.## Documentation
- [SuperDeno Deno Docs](https://doc.deno.land/https/deno.land/x/superdeno/mod.ts)
- [SuperDeno Type Docs](https://cmorten.github.io/superdeno/)
- [License](https://github.com/cmorten/superdeno/blob/main/LICENSE.md)
- [Changelog](https://github.com/cmorten/superdeno/blob/main/.github/CHANGELOG.md)## API
You may use any [superagent](http://github.com/visionmedia/superagent) client
(browser) methods and perform assertions in the `.end()` callback for
lower-level needs.### .expect(status[, fn])
Assert response `status` code.
### .expect(status, body[, fn])
Assert response `status` code and `body`.
### .expect(body[, fn])
Assert response `body` text with a string, regular expression, or parsed body
object.### .expect(field, value[, fn])
Assert header `field` `value` with a string or regular expression.
### .expect(function(res) {})
Pass a custom assertion function. It'll be given the response object to check.
If the check fails, throw an error.```ts
function hasPreviousAndNextKeys(res) {
if (!("next" in res.parsedBody)) throw new Error("missing next key");
if (!("prev" in res.parsedBody)) throw new Error("missing prev key");
}await superdeno(app).get("/").expect(hasPreviousAndNextKeys);
```### .end(fn)
Perform the request and invoke `fn(err, res)`.
## Notes
This is a port of [supertest](https://github.com/visionmedia/supertest) to
TypeScript + Deno, which fulfills this motivation currently for Node. This
module also includes a XHR sham so
[superagent](https://visionmedia.github.io/superagent/) client mode can be used
directly.## Contributing
[Contributing guide](https://github.com/cmorten/superdeno/blob/main/.github/CONTRIBUTING.md)
---
## License
This library is a port of [supertest](https://github.com/visionmedia/supertest)
whose license and copyrights are available at
[SUPERTEST_LICENSE](./SUPERTEST_LICENSE.md) in the root of this repository, and
covers all files within the [source](./src) directory which detail that the file
is a port.SuperDeno is licensed under the [MIT License](./LICENSE.md).
Icon designed and created by
[Hannah Morten](https://www.linkedin.com/in/hannah-morten-b1218017a/).