fresh icon indicating copy to clipboard operation
fresh copied to clipboard

Add a function to get a server class instance.

Open Octo8080X opened this issue 2 years ago • 3 comments

I cut out the function that gets an instance of the server from the start function.

The purpose is to prepare you to create tests for your application. The introduction of this feature does not affect fresh.

Example:

// main_test.ts

/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />
/// <reference lib="deno.unstable" />

import { getServer } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";

import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import {
  Document,
  DOMParser,
} from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";

Deno.test("HTTP assert test.", async (t) => {
  await t.step("#1 GET /", async () => {
    const server = await getServer(manifest);

    await superdeno(server)
      .get("/")
      .expect(200);
  });

  await t.step("#2 GET /Foo", async () => {
    const server = await getServer(manifest);

    const r = await superdeno(server)
      .get("/Foo")
      .expect(200);

    const document: Document = new DOMParser().parseFromString(
      r.text,
      "text/html",
    )!;

    assertEquals(document.querySelector("div")?.innerText, "Hello Foo");
  });

  await t.step("#3 GET /Foo/Bar", async () => {
    const server = await getServer(manifest);

    await superdeno(server)
      .get("/Foo/Bar")
      .expect(404);
  });
});
$ deno test --allow-net --allow-env --allow-read main_test.ts
Checked 11 files
running 1 test from ./main_test.ts
HTTP assert test. ...
  #1 GET / ... ok (58ms)
  #2 GET /Foo ... ok (56ms)
  #3 GET /Foo/Bar ... ok (42ms)
HTTP assert test. ... ok (162ms)

ok | 1 passed (3 steps) | 0 failed (295ms)

Octo8080X avatar Jul 26 '22 13:07 Octo8080X

What if we add a createHandler(manifest, opts) function instead? It can just be implemented as follows:

export async function createHandler(
  routes: Manifest,
  opts: StartOptions = {},
) {
  const ctx = await ServerContext.fromManifest(routes, opts);
  return ctx.handler();
}

superdeno also accepts handler functions instead of a full blown http.Server.

lucacasonato avatar Jul 30 '22 15:07 lucacasonato

Thank you for your interest. I have implemented createHandler(manifest, opts) in src/server/mod.ts.

export async function createHandler(
  routes: Manifest,
  opts: StartOptions = {},
) {
  const ctx = await ServerContext.fromManifest(routes, opts);
  return ctx.handler();
}

I confirmed that it works by adding --no-check. It seems to work faster.

$ deno test -A --no-check main_test.ts
Checked 14 files
running 1 test from ./main_test.ts
HTTP assert test. ...
  #1 GET / ... ok (58ms)
HTTP assert test. ... ok (63ms)

ok | 1 passed (1 step) | 0 failed (133ms)

The error in the type check was the following.

$ deno test -A main_test.ts
Checked 14 files
Check file:///usr/src/app/my-project/main_test.ts
error: TS2345 [ERROR]: Argument of type 'Handler' is not assignable to parameter of type 'string | RequestHandlerLike | ListenerLike | ServerLike'.
  Type 'Handler' is not assignable to type 'RequestHandlerLike'.
    await superdeno(handler)
                    ~~~~~~~

As a workaround, we can use assertions.

import { createHandler } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";

import { superdeno } from "https://deno.land/x/superdeno/mod.ts";
import {
  type RequestHandlerLike,
} from "https://deno.land/x/superdeno/src/types.ts";

Deno.test("HTTP assert test.", async (t) => {
  await t.step("#1 GET /", async () => {
    const handler = await createHandler(manifest) as RequestHandlerLike;

    await superdeno(handler)
      .get("/")
      .expect(200);
  });
});
$ deno test -A main_test.ts
Checked 14 files
running 1 test from ./main_test.ts
HTTP assert test. ...
  #1 GET / ... ok (56ms)
HTTP assert test. ... ok (63ms)

Errors in type checking should probably be addressed with superdeno.

We think the direction you suggested is better as it also speeds up the process.

Octo8080X avatar Jul 31 '22 02:07 Octo8080X

@lucacasonato

We have created another pull request based on the ideas we received. Once the new one is adopted, this pull request will be closed.

Add a function to create handler.

Thank you.

Octo8080X avatar Aug 15 '22 14:08 Octo8080X

Closing in favour of your superseding PR.

lucacasonato avatar May 29 '23 10:05 lucacasonato