|
| 1 | +import { describe, expect } from "bun:test" |
| 2 | +import { Config, ConfigProvider, Context, Effect, Layer, Option } from "effect" |
| 3 | +import { ConfigService } from "../../src/effect/config-service" |
| 4 | +import { it } from "../lib/effect" |
| 5 | + |
| 6 | +class TestConfig extends ConfigService.Service<TestConfig>()("@test/ConfigService", { |
| 7 | + name: Config.string("NAME"), |
| 8 | + token: Config.string("TOKEN").pipe(Config.option), |
| 9 | + port: Config.number("PORT").pipe(Config.withDefault(3000)), |
| 10 | +}) {} |
| 11 | + |
| 12 | +const fromConfig = (input: Record<string, unknown>) => |
| 13 | + TestConfig.defaultLayer.pipe(Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown(input)))) |
| 14 | + |
| 15 | +const readConfig = TestConfig.useSync((config) => config) |
| 16 | + |
| 17 | +describe("ConfigService", () => { |
| 18 | + it.effect("defaultLayer parses values from the active ConfigProvider", () => |
| 19 | + Effect.gen(function* () { |
| 20 | + const config = yield* readConfig.pipe( |
| 21 | + Effect.provide( |
| 22 | + fromConfig({ |
| 23 | + NAME: "kit", |
| 24 | + TOKEN: "secret", |
| 25 | + PORT: "4096", |
| 26 | + }), |
| 27 | + ), |
| 28 | + ) |
| 29 | + |
| 30 | + expect(config.name).toBe("kit") |
| 31 | + expect(config.token).toEqual(Option.some("secret")) |
| 32 | + expect(config.port).toBe(4096) |
| 33 | + }), |
| 34 | + ) |
| 35 | + |
| 36 | + it.effect("defaultLayer applies Effect Config defaults", () => |
| 37 | + Effect.gen(function* () { |
| 38 | + const config = yield* readConfig.pipe(Effect.provide(fromConfig({ NAME: "kit" }))) |
| 39 | + |
| 40 | + expect(config.name).toBe("kit") |
| 41 | + expect(config.token).toEqual(Option.none()) |
| 42 | + expect(config.port).toBe(3000) |
| 43 | + }), |
| 44 | + ) |
| 45 | + |
| 46 | + it.effect("layer provides an already parsed service value", () => |
| 47 | + Effect.gen(function* () { |
| 48 | + const config = yield* readConfig.pipe( |
| 49 | + Effect.provide( |
| 50 | + TestConfig.layer({ |
| 51 | + name: "direct", |
| 52 | + token: Option.some("parsed"), |
| 53 | + port: 9000, |
| 54 | + }), |
| 55 | + ), |
| 56 | + ) |
| 57 | + |
| 58 | + expect(config).toEqual({ |
| 59 | + name: "direct", |
| 60 | + token: Option.some("parsed"), |
| 61 | + port: 9000, |
| 62 | + } satisfies Context.Service.Shape<typeof TestConfig>) |
| 63 | + }), |
| 64 | + ) |
| 65 | +}) |
0 commit comments