1import { assert, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as Exit from "effect/Exit";
4import * as Latch from "effect/Latch";
5
6import { publishPlatformsThenLauncher } from "./publishOrder.ts";
7
8const platformTarballs = ["a.tgz", "b.tgz", "c.tgz"];
9const launcherTarball = "t3.tgz";
10
11// A fake publish that records when each upload starts and ends. Platform
12// uploads only end once every platform upload has started, so they have to
13// run at the same time. `failing` fails as soon as it starts.
14const fakePublish = Effect.fn("fakePublish")(function* (failing?: string) {
15 const events: Array<string> = [];
16 const allStarted = yield* Latch.make();
17 let started = 0;
18 const publish = (tarball: string) =>
19 Effect.gen(function* () {
20 events.push(`start ${tarball}`);
21 if (tarball === launcherTarball) return;
22 started += 1;
23 if (started === platformTarballs.length) yield* allStarted.open;
24 if (tarball === failing) return yield* Effect.fail(`${tarball} failed`);
25 yield* allStarted.await;
26 events.push(`end ${tarball}`);
27 });
28 return { events, publish };
29});
30
31it.effect("publishes the platform packages at once and the launcher last", () =>
32 Effect.gen(function* () {
33 const { events, publish } = yield* fakePublish();
34
35 yield* publishPlatformsThenLauncher({ platformTarballs, launcherTarball, publish });
36
37 assert.deepStrictEqual(events.slice(0, 3).toSorted(), [
38 "start a.tgz",
39 "start b.tgz",
40 "start c.tgz",
41 ]);
42 assert.strictEqual(events.at(-1), `start ${launcherTarball}`);
43 }),
44);
45
46it.effect("finishes the other uploads and skips the launcher when one fails", () =>
47 Effect.gen(function* () {
48 const { events, publish } = yield* fakePublish("b.tgz");
49
50 const exit = yield* Effect.exit(
51 publishPlatformsThenLauncher({ platformTarballs, launcherTarball, publish }),
52 );
53
54 assert.deepStrictEqual(exit, Exit.fail("b.tgz failed"));
55 assert.includeMembers(events, ["end a.tgz", "end c.tgz"]);
56 assert.notInclude(events, `start ${launcherTarball}`);
57 }),
58);