176 lines · 5.4 KB · TypeScript
RawDownload
import { describe, expect, it } from "@effect/vitest";import type { ApplicationStoredEvent, OrchestrationV2ShellSnapshot } from "@t3tools/contracts";import * as Effect from "effect/Effect";import * as Stream from "effect/Stream"; import {  coalesceShellApplicationEvents,  composeShellStreamWithEnrichment,  shellStreamItemFromEnrichmentRefresh,  shellStreamItemsFromInitialSnapshot,} from "./ShellStream.ts"; function project(sequence: number, id: string): ApplicationStoredEvent {  return {    sequence,    aggregateKind: "project",    aggregateId: id,  } as ApplicationStoredEvent;} function thread(sequence: number, id: string): ApplicationStoredEvent {  return {    sequence,    event: { threadId: id },  } as ApplicationStoredEvent;} const emptyShellSnapshot = {  schemaVersion: 1,  snapshotSequence: 0,  projects: [],  threads: [],  archivedThreads: [],} as OrchestrationV2ShellSnapshot; describe("coalesceShellApplicationEvents", () => {  it("keeps the newest event per aggregate and preserves sequence order", () => {    expect(      coalesceShellApplicationEvents([        thread(2, "thread-a"),        project(3, "project-a"),        thread(4, "thread-b"),        thread(5, "thread-a"),        project(6, "project-a"),      ]).map((event) => event.sequence),    ).toEqual([4, 5, 6]);  });}); describe("shellStreamItemFromEnrichmentRefresh", () => {  it("batches nearby completion roots onto one snapshot item", () => {    expect(      shellStreamItemFromEnrichmentRefresh({        snapshot: emptyShellSnapshot,        changes: [          { workspaceRoot: "/workspace/a" },          { workspaceRoot: "/workspace/b" },          { workspaceRoot: "/workspace/a" },        ],      }),    ).toEqual({      kind: "snapshot",      snapshot: emptyShellSnapshot,      resolvedRepositoryIdentityRoots: ["/workspace/a", "/workspace/b"],    });  });}); describe("shellStreamItemsFromInitialSnapshot", () => {  it("emits unmarked authoritative then same-sequence marked enrichment when roots resolved", () => {    const snapshot = {      ...emptyShellSnapshot,      snapshotSequence: 7,    } as OrchestrationV2ShellSnapshot;     expect(      shellStreamItemsFromInitialSnapshot({        snapshot,        resolvedRepositoryIdentityRoots: ["/workspace/a", "/workspace/a"],      }),    ).toEqual([      { kind: "snapshot", snapshot },      {        kind: "snapshot",        snapshot,        resolvedRepositoryIdentityRoots: ["/workspace/a"],      },    ]);  });   it("emits only the unmarked authoritative snapshot when no roots resolved", () => {    expect(      shellStreamItemsFromInitialSnapshot({        snapshot: emptyShellSnapshot,        resolvedRepositoryIdentityRoots: [],      }),    ).toEqual([{ kind: "snapshot", snapshot: emptyShellSnapshot }]);  });}); describe("composeShellStreamWithEnrichment", () => {  it.effect(    "emits every initial item before enrichment even when enrichment is already ready",    () =>      Effect.gen(function* () {        const initialSnapshot = {          ...emptyShellSnapshot,          snapshotSequence: 5,        } as OrchestrationV2ShellSnapshot;        const enrichmentSnapshot = {          ...emptyShellSnapshot,          snapshotSequence: 10,        } as OrchestrationV2ShellSnapshot;         const initialItems = shellStreamItemsFromInitialSnapshot({          snapshot: initialSnapshot,          resolvedRepositoryIdentityRoots: ["/workspace/a"],        });        // Enrichment stream is fully ready before the composed stream is pulled.        const enrichment = Stream.make(          shellStreamItemFromEnrichmentRefresh({            snapshot: enrichmentSnapshot,            changes: [{ workspaceRoot: "/workspace/b" }],          }),        );        const tail = Stream.make(          { kind: "synchronized" as const },          {            kind: "project.removed" as const,            sequence: 6,            projectId: "project-a",          },        );         const items = Array.from(          yield* composeShellStreamWithEnrichment({            initial: Stream.fromIterable(initialItems),            tail,            enrichment,          }).pipe(Stream.runCollect),        );         expect(items.slice(0, initialItems.length)).toEqual(initialItems);         const enrichmentIndex = items.findIndex(          (item) =>            item.kind === "snapshot" &&            "resolvedRepositoryIdentityRoots" in item &&            item.resolvedRepositoryIdentityRoots?.includes("/workspace/b"),        );        expect(enrichmentIndex).toBeGreaterThanOrEqual(initialItems.length);         for (let index = 0; index < initialItems.length; index++) {          expect(items[index]).toEqual(initialItems[index]);        }      }),  );   it.effect("still interleaves enrichment with the post-prefix tail after initials drain", () =>    Effect.gen(function* () {      const items = Array.from(        yield* composeShellStreamWithEnrichment({          initial: Stream.make("initial-unmarked", "initial-marked"),          tail: Stream.make("tail-a", "tail-b"),          enrichment: Stream.make("enrichment"),        }).pipe(Stream.runCollect),      );       expect(items.slice(0, 2)).toEqual(["initial-unmarked", "initial-marked"]);      expect(items).toContain("enrichment");      expect(items).toContain("tail-a");      expect(items).toContain("tail-b");      expect(items.indexOf("enrichment")).toBeGreaterThanOrEqual(2);    }),  );});

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t