Open History to see the last commit
1import { assert, describe, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as FileSystem from "effect/FileSystem";
4import * as Layer from "effect/Layer";
5import * as Option from "effect/Option";
6import * as TestClock from "effect/testing/TestClock";
7
8import * as DesktopUpdateMarker from "./DesktopUpdateMarker.ts";
9
10const remainingWait = (fileSystem: Partial<FileSystem.FileSystem>) =>
11 DesktopUpdateMarker.DesktopUpdateMarker.use((marker) => marker.remainingWait("/marker")).pipe(
12 Effect.provide(DesktopUpdateMarker.layer.pipe(Layer.provide(FileSystem.layerNoop(fileSystem)))),
13 );
14
15describe("DesktopUpdateMarker", () => {
16 it.effect.each([
17 ["fresh", '{"startedAt":0,"expiresAt":60000}', 0, Option.some(60000)],
18 ["partly elapsed", '{"startedAt":0,"expiresAt":60000}', 8000, Option.some(52000)],
19 ["expired", '{"startedAt":0,"expiresAt":60000}', 60000, Option.none()],
20 ["future", '{"startedAt":1000,"expiresAt":61000}', 0, Option.none()],
21 ["long host TTL", '{"startedAt":0,"expiresAt":600000}', 0, Option.some(60000)],
22 ["reversed", '{"startedAt":1000,"expiresAt":0}', 0, Option.none()],
23 ["missing fields", "{}", 0, Option.none()],
24 ["malformed", "not json", 0, Option.none()],
25 ] as const)("%s", ([name, contents, now, expected]) =>
26 Effect.gen(function* () {
27 let removed = false;
28 yield* TestClock.setTime(now);
29 const remaining = yield* remainingWait({
30 readFileString: () => Effect.succeed(contents),
31 remove: () =>
32 Effect.sync(() => {
33 removed = true;
34 }),
35 });
36 assert.deepStrictEqual(remaining, expected);
37 assert.isFalse(removed, `${name}: the launcher must never delete the shared marker`);
38 }),
39 );
40
41 it.effect("honours a marker published while it is being read", () =>
42 Effect.gen(function* () {
43 yield* TestClock.setTime(0);
44 const remaining = yield* remainingWait({
45 readFileString: () =>
46 TestClock.adjust(1000).pipe(Effect.as('{"startedAt":1000,"expiresAt":61000}')),
47 });
48 assert.deepStrictEqual(remaining, Option.some(60000));
49 }),
50 );
51
52 it.effect("a missing marker allows launch", () =>
53 Effect.gen(function* () {
54 assert.isTrue(Option.isNone(yield* remainingWait({})));
55 }),
56 );
57});