Skip to content

Commit

Permalink
test: complete coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxken committed Aug 10, 2021
1 parent d4a7f10 commit a01a8ed
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,4 @@ dist
.pnp.*

tmp/
test/download
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Thanks to undici:

- Support [HTTP redirections](https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections) with the `maxRedirections` argument.
- Implement high-level API for undici **stream** and **pipeline** method.
- Optimization and performance of the new client (**around 2.5x faster** than Node.js native http client).
- High performance (see [benchmarks](https://undici.nodejs.org/#/?id=benchmarks)).
- Work well with **newest** Node.js API [AbortController](https://nodejs.org/dist/latest-v16.x/docs/api/globals.html#globals_class_abortcontroller) to cancel http request.

Light with seriously maintained dependencies:
Expand Down
6 changes: 4 additions & 2 deletions src/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { ReqOptions } from "./request";
import { computeURI } from "./agents";
import * as Utils from "./utils";

export function pipeline(method: string, uri: string | URL, options: Omit<ReqOptions, "limit"> = {}): Duplex {
export type StreamOptions = Omit<ReqOptions, "limit">;

export function pipeline(method: string, uri: string | URL, options: StreamOptions = {}): Duplex {
const { maxRedirections = 0 } = options;
const computedURI = computeURI(uri);

Expand All @@ -24,7 +26,7 @@ export function pipeline(method: string, uri: string | URL, options: Omit<ReqOpt

export type WritableStreamCallback = (writable: Writable) => Promise<undici.Dispatcher.StreamData>;

export function stream(method: string, uri: string | URL, options: Omit<ReqOptions, "limit"> = {}): WritableStreamCallback {
export function stream(method: string, uri: string | URL, options: StreamOptions = {}): WritableStreamCallback {
const { maxRedirections = 0 } = options;
const computedURI = computeURI(uri);

Expand Down
9 changes: 9 additions & 0 deletions test/agents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,13 @@ describe("computeURI", () => {

expect(result).toStrictEqual(true);
});

it("should compute an URL not related to any local agents", () => {
const stringURL = "https://www.linkedin.com/feed/";
const result = Agents.computeURI(new URL("", stringURL));

expect(result.url.href).toStrictEqual(stringURL);
expect(result.agent).toStrictEqual(null);
expect(result.limit).toStrictEqual(undefined);
});
});
Empty file removed test/fixtures/.gitkeep
Empty file.
12 changes: 12 additions & 0 deletions test/fixtures/home.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>hello world</h1>
</body>
</html>
1 change: 1 addition & 0 deletions test/fixtures/lorem.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
2 changes: 1 addition & 1 deletion test/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
jest.setTimeout(20000);
jest.setTimeout(25000);
6 changes: 3 additions & 3 deletions test/request.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ describe("http.get", () => {
expect(typeof data.uptime).toStrictEqual("number");
});

it("should GET a ressource with an http redirection", async() => {
it("should GET uptime by following an HTTP redirection from local fastify server", async() => {
const { data } = await get<{ uptime: number }>("/local/redirect", { maxRedirections: 1 });

expect("uptime" in data).toStrictEqual(true);
expect(typeof data.uptime).toStrictEqual("number");
});

it("should GET uptime with a limit wrapper", async() => {
it("should GET uptime through a limit function handler from local fastify server", async() => {
let executed = false;
// eslint-disable-next-line func-style
const limit = (callback) => {
Expand Down Expand Up @@ -81,7 +81,7 @@ describe("http.get", () => {
}
});

it("should throw a SyntaxError with jsonError endpoint", async() => {
it("should throw a 'SyntaxError' with jsonError endpoint from local fastify server", async() => {
expect.assertions(1);

try {
Expand Down
32 changes: 32 additions & 0 deletions test/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
// Import Node.js Dependencies
import path from "path";
import fs from "fs";
import { Transform } from "stream";

// Import Third-party Dependencies
import fastify from "fastify";
import * as undici from "undici";

// Import Internal Dependencies
import { CustomHttpAgent, agents } from "../../src/agents";

// CONSTANTS
const kFixturesPath = path.join(__dirname, "..", "fixtures");

const toUpperCase = new Transform({
transform(chunk, enc, next) {
for (let id = 0; id < chunk.length; id++) {
const char = chunk[id];
chunk[id] = char < 97 || char > 122 ? char : char - 32;
}

this.push(chunk);
next();
}
});

export async function createServer(customPath = "local", port = 3000) {
const server = fastify({ logger: false });
const serverAgent: CustomHttpAgent = {
Expand All @@ -27,6 +47,18 @@ export async function createServer(customPath = "local", port = 3000) {
};
});

server.get("/home", (request, reply) => {
reply.send(
fs.createReadStream(path.join(kFixturesPath, "home.html"))
);
});

server.get("/pipeline", (request, reply) => {
reply.send(
request.raw.pipe(toUpperCase)
);
});

server.get("/redirect", (request, reply) => {
reply.redirect("/");
});
Expand Down
79 changes: 79 additions & 0 deletions test/stream.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Import Third-party Dependencies
import { FastifyInstance } from "fastify";

// Import Node.js Dependencies
import { createWriteStream, createReadStream, existsSync, promises as fs } from "fs";
import path from "path";
import { pipeline } from "stream/promises";

// Import Internal Dependencies
import * as httpie from "../src/index";
import { createServer } from "./server/index";

// CONSTANTS
const kGithubURL = new URL("https://github.com/");
const kFixturesPath = path.join(__dirname, "fixtures");
const kDownloadPath = path.join(__dirname, "download");

let httpServer: FastifyInstance;
beforeAll(async() => {
httpServer = await createServer("stream", 1338);
await fs.mkdir(kDownloadPath, { recursive: true });
});

afterAll(async() => {
await httpServer.close();
await fs.rm(kDownloadPath, { force: true, recursive: true });
});

describe("stream", () => {
it("should fetch a .tar.gz of a given github repository", async() => {
const fileDestination = path.join(kDownloadPath, "i18n-main.tar.gz");
const repositoryURL = new URL("NodeSecure/i18n/archive/main.tar.gz", kGithubURL);

await httpie.stream("GET", repositoryURL, {
headers: {
"User-Agent": "httpie",
"Accept-Encoding": "gzip, deflate"
},
maxRedirections: 1
})(createWriteStream(fileDestination));

expect(existsSync(fileDestination)).toStrictEqual(true);
});

it("should fetch the HTML home from the local fastify server", async() => {
const fileDestination = path.join(kDownloadPath, "home.html");

await httpie.stream("GET", "/stream/home")(createWriteStream(fileDestination));

expect(existsSync(fileDestination)).toStrictEqual(true);
const [contentA, contentB] = await Promise.all([
fs.readFile(path.join(kFixturesPath, "home.html"), "utf-8"),
fs.readFile(path.join(kDownloadPath, "home.html"), "utf-8")
]);

expect(contentA).toStrictEqual(contentB);
});
});

describe("pipeline", () => {
it("should be able to pipeline (duplex stream)", async() => {
const fixtureLocation = path.join(kFixturesPath, "lorem.txt");
const fileDestination = path.join(kDownloadPath, "lorem.txt");

await pipeline(
createReadStream(fixtureLocation),
httpie.pipeline("GET", "/stream/pipeline"),
createWriteStream(fileDestination)
);

expect(existsSync(fileDestination)).toStrictEqual(true);
const [contentA, contentB] = await Promise.all([
fs.readFile(fixtureLocation, "utf-8"),
fs.readFile(fileDestination, "utf-8")
]);

expect(contentA.toUpperCase()).toStrictEqual(contentB);
});
});

0 comments on commit a01a8ed

Please sign in to comment.