From 6fa34069ea75816c53fedc89fe7b7e46f5cfe3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 24 Mar 2026 11:22:25 +0100 Subject: [PATCH] Add Lens tests --- packages/effect-fc/src/Lens.test.ts | 99 +++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 packages/effect-fc/src/Lens.test.ts diff --git a/packages/effect-fc/src/Lens.test.ts b/packages/effect-fc/src/Lens.test.ts new file mode 100644 index 0000000..b2a5fe3 --- /dev/null +++ b/packages/effect-fc/src/Lens.test.ts @@ -0,0 +1,99 @@ +import { describe, expect, test } from "bun:test" +import { Chunk, Effect, SubscriptionRef } from "effect" +import * as Lens from "./Lens.js" + + +describe("Lens", () => { + test("mapField focuses a nested property without touching other fields", async () => { + const [initialCount, updatedState] = await Effect.runPromise( + Effect.flatMap( + SubscriptionRef.make({ count: 1, label: "original" }), + parent => { + const countLens = Lens.mapField(Lens.fromSubscriptionRef(parent), "count") + return Effect.flatMap( + Lens.get(countLens), + count => Effect.flatMap( + Lens.set(countLens, count + 5), + () => Effect.map(parent.get, state => [count, state] as const), + ), + ) + }, + ), + ) + + expect(initialCount).toBe(1) + expect(updatedState).toEqual({ count: 6, label: "original" }) + }) + + test("mapMutableField preserves the root identity when mutating in place", async () => { + const original = { detail: "keep" } + const updated = await Effect.runPromise( + Effect.flatMap( + SubscriptionRef.make(original), + parent => { + const detailLens = Lens.mapMutableField(Lens.fromSubscriptionRef(parent), "detail") + return Effect.flatMap( + Lens.set(detailLens, "mutated"), + () => parent.get, + ) + }, + ), + ) + + expect(updated).toBe(original) + expect(updated.detail).toBe("mutated") + }) + + test("mapArrayAt updates the selected index", async () => { + const updated = await Effect.runPromise( + Effect.flatMap( + SubscriptionRef.make([10, 20, 30]), + parent => { + const elementLens = Lens.mapArrayAt(Lens.fromSubscriptionRef(parent), 1) + return Effect.flatMap( + Lens.update(elementLens, value => value + 5), + () => parent.get, + ) + }, + ), + ) + + expect(updated).toEqual([10, 25, 30]) + }) + + test("mapMutableArrayAt mutates the array reference in place", async () => { + const original = ["foo", "bar"] + const updated = await Effect.runPromise( + Effect.flatMap( + SubscriptionRef.make(original), + parent => { + const elementLens = Lens.mapMutableArrayAt(Lens.fromSubscriptionRef(parent), 0) + return Effect.flatMap( + Lens.set(elementLens, "baz"), + () => parent.get, + ) + }, + ), + ) + + expect(updated).toBe(original) + expect(updated).toEqual(["baz", "bar"]) + }) + + test("mapChunkAt replaces the focused chunk element", async () => { + const updated = await Effect.runPromise( + Effect.flatMap( + SubscriptionRef.make(Chunk.make(1, 2, 3) as Chunk.Chunk), + parent => { + const elementLens = Lens.mapChunkAt(Lens.fromSubscriptionRef(parent), 2) + return Effect.flatMap( + Lens.set(elementLens, 99), + () => parent.get, + ) + }, + ), + ) + + expect(Chunk.toReadonlyArray(updated)).toEqual([1, 2, 99]) + }) +})