Skip to content

Commit

Permalink
test: add serve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aralroca committed Oct 4, 2023
1 parent 7ae19de commit 01d295a
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 38 deletions.
4 changes: 2 additions & 2 deletions cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if [ "$1" = "dev" ]; then
esac
shift
done
NODE_ENV=development $BUN_EXEC --hot node_modules/brisa/out/cli/dev/serve.js $PORT
NODE_ENV=development $BUN_EXEC --hot node_modules/brisa/out/cli/dev/index.js $PORT

# brisa build
elif [ "$1" = "build" ]; then
Expand All @@ -54,7 +54,7 @@ elif [ "$1" = "start" ]; then
esac
shift
done
NODE_ENV=production $BUN_EXEC node_modules/brisa/out/cli/serve.js $PORT
NODE_ENV=production $BUN_EXEC node_modules/brisa/out/cli/serve/index.js $PORT

# brisa --help
else
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"scripts": {
"build": "bun run clean && bun run build:jsx-runtime && bun run build:jsx-dev-runtime && bun run build:core",
"build:core": "bun build --minify --target=bun --outdir=out/core src/core/index.ts && bun run build:cli && cp src/types/index.d.ts out/core/index.d.ts",
"build:cli": "NODE_ENV=production bun build --minify --target=bun --outdir=out/cli src/cli/build.ts src/cli/serve.tsx && NODE_ENV=development bun build --minify --target=bun --outdir=out/cli/dev src/cli/serve.tsx",
"build:cli": "NODE_ENV=production bun build --minify --target=bun --outdir=out/cli src/cli/build.ts src/cli/serve/index.tsx && NODE_ENV=development bun build --minify --target=bun --outdir=out/cli/dev src/cli/serve/index.tsx",
"build:jsx-runtime": "bun build --minify --target=bun --outdir=jsx-runtime src/jsx-runtime/index.ts && cp src/types/index.d.ts jsx-runtime/index.d.ts",
"build:jsx-dev-runtime": "bun build --minify --target=bun --outdir=jsx-dev-runtime src/jsx-runtime/index.ts && cp src/types/index.d.ts jsx-dev-runtime/index.d.ts",
"test": "bun test",
Expand Down
14 changes: 14 additions & 0 deletions src/__fixtures__/api/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type RequestContext } from "../../types";

export function GET(request: RequestContext) {
return new Response(JSON.stringify({ hello: "world" }), {
headers: { "content-type": "application/json" },
});
}

export async function POST(request: RequestContext) {
const formData = await request.formData();
const name = formData.get("name");
const email = formData.get("email");
return new Response(JSON.stringify({ name, email }));
}
2 changes: 1 addition & 1 deletion src/__fixtures__/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export default function Layout({ children }: { children: JSX.Element }) {
return (
<html>
<head>
<title>CUSTOM LAYOUT</title>
<title id="title">CUSTOM LAYOUT</title>
</head>
<body>{children}</body>
</html>
Expand Down
8 changes: 7 additions & 1 deletion src/__fixtures__/pages/_404.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
// for testing purposes
export const Head = () => {
return <title id="title">Page not found</title>;
};

export default async function _404() {
return <h1>Page not found 404</h1>;
}
4 changes: 3 additions & 1 deletion src/__fixtures__/pages/somepage.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
// for testing purposes
export default async function SomePage() {
return <h1>Some page</h1>;
}
Empty file removed src/cli/serve.test.tsx
Empty file.
24 changes: 24 additions & 0 deletions src/cli/serve/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import fs from "node:fs";
import getConstants from "../../constants";
import { serveOptions } from "./serve-options";

const { IS_PRODUCTION, ROOT_DIR, PAGES_DIR } = getConstants();

if (IS_PRODUCTION && !fs.existsSync(ROOT_DIR)) {
console.error('Not exist "build" yet. Please run "brisa build" first');
process.exit(1);
}

if (!fs.existsSync(PAGES_DIR)) {
const path = IS_PRODUCTION ? "build/pages" : "src/pages";
const cli = IS_PRODUCTION ? "brisa start" : "brisa dev";

console.error(`Not exist ${path}" directory. It\'s required to run "${cli}"`);
process.exit(1);
}

const server = Bun.serve(serveOptions);

console.log(
`Listening on http://localhost:${server.port} (${process.env.NODE_ENV})...`,
);
108 changes: 108 additions & 0 deletions src/cli/serve/serve-options.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import path from "node:path";
import {
describe,
it,
expect,
beforeEach,
afterEach,
beforeAll,
afterAll,
} from "bun:test";
import getConstants from "../../constants";
import { Serve, gc } from "bun";
import { GlobalRegistrator } from "@happy-dom/global-registrator";

const ROOT_DIR = path.join(import.meta.dir, "..", "..", "__fixtures__");

const PAGES_DIR = path.join(ROOT_DIR, "pages");
const ASSETS_DIR = path.join(ROOT_DIR, "assets");
let serveOptions: Serve;

function testRequest(request: Request): Response {
return (
// @ts-ignore
(serveOptions.fetch(request, { requestIP: () => {}, upgrade: () => {} }) ||
new Response()) as Response
);
}

describe("CLI: serve", () => {
beforeAll(() => {
GlobalRegistrator.unregister();
});

afterAll(() => {
GlobalRegistrator.register();
});

beforeEach(async () => {
globalThis.mockConstants = {
...(getConstants() ?? {}),
PAGES_DIR,
ROOT_DIR,
SRC_DIR: ROOT_DIR,
ASSETS_DIR,
I18N_CONFIG: {
locales: ["en", "es"],
defaultLocale: "es",
},
};
serveOptions = (await import("./serve-options")).serveOptions;
});

afterEach(() => {
globalThis.mockConstants = undefined;
gc(true);
});

it("should return 404 page", async () => {
const response = await testRequest(
new Request("http://localhost:1234/es/not-found-page"),
);
const html = await response.text();

expect(response.status).toBe(404);
expect(html).toContain('<title id="title">Page not found</title>');
expect(html).not.toContain('<title id="title">CUSTOM LAYOUT</title>');
expect(html).toContain("<h1>Page not found 404</h1>");
});

it("should return a page with layout and i18n", async () => {
const response = await testRequest(
new Request(`http://localhost:1234/es/somepage`),
);
const html = await response.text();
expect(response.status).toBe(200);
expect(html).toContain('<html lang="es">');
expect(html).toContain('<title id="title">CUSTOM LAYOUT</title>');
expect(html).toContain("<h1>Some page</h1>");
});

it("should be possible to fetch an api route GET", async () => {
const response = await testRequest(
new Request(`http:///localhost:1234/es/api/example`),
);
const json = await response.json();

expect(response.status).toBe(200);
expect(json).toEqual({ hello: "world" });
});

it("should be possible to fetch an api route POST with a FormData", async () => {
const body = new FormData();

body.append("name", "Brisa");
body.append("email", "[email protected]");

const response = await testRequest(
new Request(`http:///localhost:1234/es/api/example`, {
method: "POST",
body,
}),
);
const json = await response.json();

expect(response.status).toBe(200);
expect(json).toEqual({ name: "Brisa", email: "[email protected]" });
});
});
47 changes: 15 additions & 32 deletions src/cli/serve.tsx → src/cli/serve/serve-options.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import fs from "node:fs";
import path from "node:path";

import LoadLayout from "../utils/load-layout";
import getRouteMatcher from "../utils/get-route-matcher";
import { renderToReadableStream } from "../core";
import { LiveReloadScript } from "./dev-live-reload";
import { MatchedRoute, ServerWebSocket } from "bun";
import importFileIfExists from "../utils/import-file-if-exists";
import getConstants from "../constants";
import handleI18n from "../utils/handle-i18n";
import redirectTrailingSlash from "../utils/redirect-trailing-slash";
import getImportableFilepath from "../utils/get-importable-filepath";
import extendRequestContext from "../utils/extend-request-context";
import { RequestContext } from "../types";
import LoadLayout from "../../utils/load-layout";
import getRouteMatcher from "../../utils/get-route-matcher";
import { renderToReadableStream } from "../../core";
import { LiveReloadScript } from "../dev-live-reload";
import { MatchedRoute, Serve, Server, ServerWebSocket } from "bun";
import importFileIfExists from "../../utils/import-file-if-exists";
import getConstants from "../../constants";
import handleI18n from "../../utils/handle-i18n";
import redirectTrailingSlash from "../../utils/redirect-trailing-slash";
import getImportableFilepath from "../../utils/get-importable-filepath";
import extendRequestContext from "../../utils/extend-request-context";
import { RequestContext } from "../../types";

const {
IS_PRODUCTION,
Expand All @@ -32,19 +32,6 @@ declare global {
var ws: ServerWebSocket<unknown> | undefined;
}

if (IS_PRODUCTION && !fs.existsSync(ROOT_DIR)) {
console.error('Not exist "build" yet. Please run "brisa build" first');
process.exit(1);
}

if (!fs.existsSync(PAGES_DIR)) {
const path = IS_PRODUCTION ? "build/pages" : "src/pages";
const cli = IS_PRODUCTION ? "brisa start" : "brisa dev";

console.error(`Not exist ${path}" directory. It\'s required to run "${cli}"`);
process.exit(1);
}

const middlewareModule = await importFileIfExists("middleware", ROOT_DIR);
const customMiddleware = middlewareModule?.default;
let pagesRouter = getRouteMatcher(PAGES_DIR, RESERVED_PAGES);
Expand All @@ -57,8 +44,8 @@ const responseInitWithGzip = {
},
};

// Start server
Bun.serve({
// Options to start server
export const serveOptions: Serve = {
port: PORT,
development: !IS_PRODUCTION,
async fetch(req: Request, server) {
Expand Down Expand Up @@ -114,11 +101,7 @@ Bun.serve({
wsModule?.drain?.(ws);
},
},
});

console.log(
`Listening on http://localhost:${PORT} (${process.env.NODE_ENV})...`,
);
};

///////////////////////////////////////////////////////
////////////////////// HELPERS ///////////////////////
Expand Down

0 comments on commit 01d295a

Please sign in to comment.