Skip to content

Commit

Permalink
add {Bun,Node}HttpServer.layerTest for testing http servers (#3409)
Browse files Browse the repository at this point in the history
  • Loading branch information
sukovanej authored Aug 7, 2024
1 parent 818ea47 commit 056b710
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 113 deletions.
20 changes: 20 additions & 0 deletions .changeset/cyan-mugs-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@effect/platform-node": patch
---

Add `NodeHttpServer.layerTest`.

```ts
import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform"
import { NodeHttpServer } from "@effect/platform-node"
import { expect, it } from "@effect/vitest"
import { Effect } from "effect"

it.scoped("test", () =>
Effect.gen(function* () {
yield* HttpServer.serveEffect(HttpRouter.empty)
const response = yield* HttpClientRequest.get("/")
expect(response.status, 404)
}).pipe(Effect.provide(NodeHttpServer.layerTest))
)
```
19 changes: 19 additions & 0 deletions .changeset/happy-glasses-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@effect/platform-bun": patch
---

Add `BunHttpServer.layerTest`.

```ts
import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform"
import { BunHttpServer } from "@effect/platform-bun"
import { expect, it } from "bun:test"
import { Effect } from "effect"

it("test", () =>
Effect.gen(function* (_) {
yield* HttpServer.serveEffect(HttpRouter.empty)
const response = yield* HttpClientRequest.get("/non-existing")
expect(response.status).toEqual(404)
}).pipe( Effect.provide(BunHttpServer.layerTest), Effect.scoped, Effect.runPromise))
```
5 changes: 5 additions & 0 deletions .changeset/wicked-dragons-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/platform": patch
---

Add `HttpClient.layerTest`.
4 changes: 1 addition & 3 deletions packages/platform-bun/docgen.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"$schema": "../../node_modules/@effect/docgen/schema.json",
"exclude": [
"src/internal/**/*.ts"
]
"exclude": ["src/internal/**/*.ts"]
}
18 changes: 18 additions & 0 deletions packages/platform-bun/src/BunHttpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
* @since 1.0.0
*/
import type * as Etag from "@effect/platform/Etag"
import type * as HttpClient from "@effect/platform/HttpClient"
import type * as Platform from "@effect/platform/HttpPlatform"
import type * as Server from "@effect/platform/HttpServer"
import type * as HttpServerError from "@effect/platform/HttpServerError"
import type { ServeOptions } from "bun"
import type * as Config from "effect/Config"
import type * as ConfigError from "effect/ConfigError"
Expand Down Expand Up @@ -36,6 +38,22 @@ export const layer: (
options: Omit<ServeOptions, "fetch" | "error">
) => Layer.Layer<Server.HttpServer | Platform.HttpPlatform | Etag.Generator | BunContext.BunContext> = internal.layer

/**
* Layer starting a server on a random port and producing an `HttpClient`
* with prepended url of the running http server.
*
* @since 1.0.0
* @category layers
*/
export const layerTest: Layer.Layer<
| HttpClient.HttpClient.Default
| Server.HttpServer
| Platform.HttpPlatform
| Etag.Generator
| BunContext.BunContext,
HttpServerError.ServeError
> = internal.layerTest

/**
* @since 1.0.0
* @category layers
Expand Down
12 changes: 12 additions & 0 deletions packages/platform-bun/src/internal/httpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as Cookies from "@effect/platform/Cookies"
import type * as FileSystem from "@effect/platform/FileSystem"
import * as Headers from "@effect/platform/Headers"
import * as App from "@effect/platform/HttpApp"
import * as HttpClient from "@effect/platform/HttpClient"
import * as IncomingMessage from "@effect/platform/HttpIncomingMessage"
import type { HttpMethod } from "@effect/platform/HttpMethod"
import * as Server from "@effect/platform/HttpServer"
Expand Down Expand Up @@ -177,6 +178,17 @@ export const layer = (
BunContext.layer
)

/** @internal */
export const layerTest = Server.layerTestClient.pipe(
Layer.provide(Layer.succeed(
HttpClient.HttpClient,
HttpClient.fetch.pipe(
HttpClient.transformResponse(HttpClient.withFetchOptions({ keepalive: false }))
)
)),
Layer.provideMerge(layer({ port: 0 }))
)

/** @internal */
export const layerConfig = (
options: Config.Config.Wrap<Omit<ServeOptions, "fetch" | "error">>
Expand Down
18 changes: 18 additions & 0 deletions packages/platform-bun/test-bun/BunHttpServer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { HttpClientRequest, HttpRouter, HttpServer, HttpServerResponse } from "@effect/platform"
import { BunHttpServer } from "@effect/platform-bun"
import { expect, it } from "bun:test"
import { Effect } from "effect"

it("BunHttpTest", () =>
Effect.gen(function*(_) {
yield* HttpRouter.empty.pipe(
HttpRouter.get("/", HttpServerResponse.text("Hello, World!")),
HttpServer.serveEffect()
)
const response1 = yield* HttpClientRequest.get("/")
expect(response1.status).toEqual(200)
expect(yield* response1.text).toEqual("Hello, World!")

const response2 = yield* HttpClientRequest.get("/non-existing")
expect(response2.status).toEqual(404)
}).pipe(Effect.provide(BunHttpServer.layerTest), Effect.scoped, Effect.runPromise))
29 changes: 26 additions & 3 deletions packages/platform-node/docgen.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
{
"$schema": "../../node_modules/@effect/docgen/schema.json",
"exclude": [
"src/internal/**/*.ts"
]
"exclude": ["src/internal/**/*.ts"],
"examplesCompilerOptions": {
"noEmit": true,
"strict": true,
"skipLibCheck": true,
"moduleResolution": "Bundler",
"module": "ES2022",
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"paths": {
"effect": ["../../../effect/src/index.js"],
"effect/*": ["../../../effect/src/*.js"],
"@effect/platform": ["../../../platform/src/index.js"],
"@effect/platform/*": ["../../../platform/src/*.js"],
"@effect/platform-node": ["../../../platform-node/src/index.js"],
"@effect/platform-node/*": ["../../../platform-node/src/*.js"],
"@effect/platform-node-shared": [
"../../../platform-node-shared/src/index.js"
],
"@effect/platform-node-shared/*": [
"../../../platform-node-shared/src/*.js"
],
"@effect/schema": ["../../../schema/src/index.js"],
"@effect/schema/*": ["../../../schema/src/*.js"]
}
}
}
28 changes: 28 additions & 0 deletions packages/platform-node/src/NodeHttpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import type * as Etag from "@effect/platform/Etag"
import type * as App from "@effect/platform/HttpApp"
import type * as HttpClient from "@effect/platform/HttpClient"
import type * as Middleware from "@effect/platform/HttpMiddleware"
import type * as Platform from "@effect/platform/HttpPlatform"
import type * as Server from "@effect/platform/HttpServer"
Expand Down Expand Up @@ -84,3 +85,30 @@ export const layerConfig: (
Platform.HttpPlatform | Etag.Generator | NodeContext.NodeContext | Server.HttpServer,
ConfigError.ConfigError | ServeError
> = internal.layerConfig

/**
* Layer starting a server on a random port and producing an `HttpClient`
* with prepended url of the running http server.
*
* @example
* import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform"
* import { NodeHttpServer } from "@effect/platform-node"
* import { Effect } from "effect"
*
* Effect.gen(function*() {
* yield* HttpServer.serveEffect(HttpRouter.empty)
* const response = yield* HttpClientRequest.get("/")
* assert.strictEqual(response.status, 404)
* }).pipe(Effect.provide(NodeHttpServer.layerTest))
*
* @since 1.0.0
* @category layers
*/
export const layerTest: Layer.Layer<
| HttpClient.HttpClient.Default
| Server.HttpServer
| Platform.HttpPlatform
| Etag.Generator
| NodeContext.NodeContext,
ServeError
> = internal.layerTest
8 changes: 8 additions & 0 deletions packages/platform-node/src/internal/httpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { Readable } from "node:stream"
import { pipeline } from "node:stream/promises"
import * as WS from "ws"
import * as NodeContext from "../NodeContext.js"
import * as NodeHttpClient from "../NodeHttpClient.js"
import * as NodeSink from "../NodeSink.js"
import { HttpIncomingMessageImpl } from "./httpIncomingMessage.js"
import * as internalPlatform from "./httpPlatform.js"
Expand Down Expand Up @@ -329,6 +330,13 @@ export const layer = (
NodeContext.layer
)

/** @internal */
export const layerTest = Server.layerTestClient.pipe(
Layer.provide(NodeHttpClient.layerWithoutAgent),
Layer.provide(NodeHttpClient.makeAgentLayer({ keepAlive: false })),
Layer.provideMerge(layer(Http.createServer, { port: 0 }))
)

/** @internal */
export const layerConfig = (
evaluate: LazyArg<Http.Server>,
Expand Down
Loading

0 comments on commit 056b710

Please sign in to comment.