Skip to content

Commit

Permalink
add RpcTest module
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed Feb 1, 2025
1 parent 3bd36df commit 5cdc4d9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
33 changes: 33 additions & 0 deletions packages/rpc/src/RpcTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @since 1.0.0
*/
import * as Effect from "effect/Effect"
import type * as Scope from "effect/Scope"
import type * as Rpc from "./Rpc.js"
import * as RpcClient from "./RpcClient.js"
import type * as RpcGroup from "./RpcGroup.js"
import * as RpcServer from "./RpcServer.js"

/**
* @since 1.0.0
* @category constructors
*/
export const makeClient: <Rpcs extends Rpc.Any>(
group: RpcGroup.RpcGroup<Rpcs>
) => Effect.Effect<
RpcClient.RpcClient<Rpcs>,
never,
Scope.Scope | Rpc.ToHandler<Rpcs> | Rpc.Middleware<Rpcs>
> = Effect.fnUntraced(function*<Rpcs extends Rpc.Any>(
group: RpcGroup.RpcGroup<Rpcs>
) {
const server = yield* RpcServer.makeNoSerialization(group)
const client = yield* RpcClient.makeNoSerialization(group, {
supportsAck: true,
onFromClient(message) {
return server.write(0, message)
}
})
yield* Effect.forkScoped(server.run(client.write))
return client.client
})
5 changes: 5 additions & 0 deletions packages/rpc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export * as RpcSerialization from "./RpcSerialization.js"
*/
export * as RpcServer from "./RpcServer.js"

/**
* @since 1.0.0
*/
export * as RpcTest from "./RpcTest.js"

/**
* @since 1.0.0
*/
Expand Down
13 changes: 11 additions & 2 deletions packages/rpc/test/RpcServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import * as NodeSocketServer from "@effect/experimental/SocketServer/Node"
import { HttpClient, HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform"
import { NodeHttpServer, NodeSocket } from "@effect/platform-node"
import { RpcClient, RpcSerialization, RpcServer } from "@effect/rpc"
import { describe } from "@effect/vitest"
import { assert, describe, it } from "@effect/vitest"
import { Effect, Layer } from "effect"
import { e2eSuite } from "./e2e.js"
import { RpcLive, UsersClient } from "./fixtures/schemas.js"
import { RpcLive, User, UsersClient } from "./fixtures/schemas.js"

describe("RpcServer", () => {
// http ndjson
Expand Down Expand Up @@ -102,4 +102,13 @@ describe("RpcServer", () => {
Layer.provide([NodeHttpServer.layerTest, RpcSerialization.layerMsgPack])
)
)

describe("RpcTest", () => {
it.effect("works", () =>
Effect.gen(function*() {
const client = yield* UsersClient
const user = yield* client.GetUser({ id: "1" })
assert.deepStrictEqual(user, new User({ id: "1", name: "Logged in user" }))
}).pipe(Effect.provide(UsersClient.layerTest)))
})
})
20 changes: 12 additions & 8 deletions packages/rpc/test/fixtures/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RpcTest } from "@effect/rpc"
import * as Rpc from "@effect/rpc/Rpc"
import * as RpcClient from "@effect/rpc/RpcClient"
import * as RpcGroup from "@effect/rpc/RpcGroup"
Expand All @@ -24,7 +25,7 @@ class StreamUsers extends Schema.TaggedRequest<StreamUsers>()("StreamUsers", {

class CurrentUser extends Context.Tag("CurrentUser")<CurrentUser, User>() {}

class AuthMiddleware extends RpcMiddleware.Tag<AuthMiddleware>()("TestMiddleware", {
class AuthMiddleware extends RpcMiddleware.Tag<AuthMiddleware>()("AuthMiddleware", {
provides: CurrentUser
}) {}

Expand All @@ -41,13 +42,6 @@ export const UserRpcs = RpcGroup
)
.middleware(AuthMiddleware)

export class UsersClient extends Context.Tag("UsersClient")<
UsersClient,
RpcClient.RpcClient<RpcGroup.Rpcs<typeof UserRpcs>>
>() {
static layer = Layer.scoped(UsersClient, RpcClient.make(UserRpcs))
}

const AuthLive = Layer.succeed(
AuthMiddleware,
AuthMiddleware.of((options) =>
Expand Down Expand Up @@ -88,3 +82,13 @@ export const RpcLive = RpcServer.layer(UserRpcs).pipe(
AuthLive
])
)

export class UsersClient extends Context.Tag("UsersClient")<
UsersClient,
RpcClient.RpcClient<RpcGroup.Rpcs<typeof UserRpcs>>
>() {
static layer = Layer.scoped(UsersClient, RpcClient.make(UserRpcs))
static layerTest = Layer.scoped(UsersClient, RpcTest.makeClient(UserRpcs)).pipe(
Layer.provide([UsersLive, AuthLive])
)
}

0 comments on commit 5cdc4d9

Please sign in to comment.